diff --git a/README.md b/README.md index 7d4a7110dfb4768da10a8c12ca118932df31ed80..8f8d930e18e6ffe63b81b7bf3950059eec4de736 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,64 @@ ## Spring Domain -  轻量级领域驱动框架。 +轻量级领域驱动框架。 -- **支持实体和数据库表联动,同步增、删、改。** -- **支持通过简单对象查询实体,而无需考虑字段所属表结构。** -- **支持实体继承,并根据类型进行动态级联查询。** +- **实现以关系数据库为基础的仓储(Repository)** + +- **实现领域事件通知机制** + +- **实现通过防腐对象查询数据聚合** -## 什么是领域驱动? +## SmartUI模式 -  在讨论什么是领域驱动之前,让我们思考一下什么是需求驱动。 +**以UI界面驱动数据库设计,再以数据库设计驱动代码开发的模式,称为“SmartUI模式”。** -## 需求驱动 +**优点:** -  从字面来理解,就是产品经理提需求,开发工程师按照需求,开展设计与编码工作。开发工程师一般先设计表结构,再通过逆向工程生成映射对象。映射对象只包含业务字段,不包含业务方法,业务逻辑都统一放在Service层。这是典型的”失血模式“。 +- 效率高,能在短时间内实现简单的应用程序。 -  需求驱动的特点: +- 对开发人员的要求低,几乎不需要培训。 -- 基本不需要复杂的设计,开发简单,可以做到快速开发和上线。 -- 设计、编码与需求耦合度高,无法应对更复杂的业务场景。 +- 有时可以克服需求分析上的不足,只需要满足原型即可。 +- 程序之间独立性高,可以相对准确地安排小的交付周期。 -## 领域驱动 +- 能够便捷地在关系数据库上构建应用。 + +- 通过UI界面,能够大致了解后台的逻辑。 + +**缺点:** + +- 应用开发,无法脱离数据库。 -  同样是产品经理提需求,开发工程师按照需求,开展设计与编码工作。不过,在设计之前,开发工程师需要思考以下几个问题: +- 没有对业务行为的提炼与复用,每次遇到相似的业务需求时,都必须重新开发。 -- 需求所属的业务领域是什么? -- 该业务领域是否存在通用的数据模型? -- 该数据模型是否存在具体的业务行为? -- 该业务领域是否存在细分的子业务领域? -- 该子业务领域中,数据模型的业务行为是否会发生变化? +- 功能迭代有一定局限性,难以拓展与重构。 + +- 面对复杂的功能,无所适从,只能做简单地修改,无法实现更加丰富的功能。 + + +## 领域驱动 -  从以上几个问题,隐约能够嗅到“面向对象编程”的味道。在领域驱动设计理念中,上述数据模型被称为“领域模型”。 +**以业务核心驱动模型设计,再以模型设计驱动代码开发的方式,称为领域驱动。** -  开发工程师一般先设计实体类(Java对象),再配置实体类和数据库表的映射关系。实体类包含业务字段,也包含业务方法,业务方法可以被子类重写。这是典型的“充血模式”。 +**优点:** -  领域模型的优势: +- 领域模型是业务知识的高度概括,容易在产品、开发、测试人员之间进行传播。 + +- 不强依赖于数据库,容易与不同的存储引擎进行集成。 + +- 领域模型通用性强,容易在不同的业务场景中复用。 + +- 实现复杂的功能比较容易,可拓展性强。 + +- 在战略层面,能借用领域模型,进行业务架构的顶层设计。 -- 与现实世界中的概念相似,容易被产品经理、前端工程师、后端工程师、测试工程师所理解。 +**缺点:** -- 允许多层嵌套,数据结构高度内聚。 +- 要求开发人员掌握一定的业务知识。 -- 具有面向对象编程的特性,支持在不同的业务领域,发生不同的业务行为。 +- 要求开发人员能够与业务人员进行充分的交流。 - 领域模型的劣势: +- 要求开发人员能够将业务知识融入到模型的开发当中。 -- 要求开发工程师对业务十分熟悉,最好是领域专家。 -- 要求开发工程师理解面向对象编程,并掌握常见的设计模式。 \ No newline at end of file +- 初期的领域模型,可能需要在后续迭代中,不断演进。 diff --git a/spring-domain-event/pom.xml b/dorive-coating/pom.xml similarity index 75% rename from spring-domain-event/pom.xml rename to dorive-coating/pom.xml index 81398f6b49251ebef7f51d04c3e03b8fcb3146dc..f78022c26efc37f3fa1a76139024879d00ff42a9 100644 --- a/spring-domain-event/pom.xml +++ b/dorive-coating/pom.xml @@ -5,15 +5,14 @@ 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 - spring-domain-event - + dorive-coating com.gitee.digital-engine - spring-domain-core + dorive-event ${project.version} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/Coating.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/Coating.java new file mode 100644 index 0000000000000000000000000000000000000000..49ab4ae92cbe5a35f3a3e6ff08e616074901b255 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/Coating.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Coating { + Class qualifier() default Object.class; +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/CoatingScan.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/CoatingScan.java new file mode 100644 index 0000000000000000000000000000000000000000..c5b6e65da97fb0f97d4beab51a3759101dcd2e2e --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/CoatingScan.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface CoatingScan { + String[] value() default {}; +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/Property.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/Property.java new file mode 100644 index 0000000000000000000000000000000000000000..d10a956ed14c713781b53309635009375b8991a1 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/annotation/Property.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Documented +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Property { + + String accessPath() default ""; + + String alias() default ""; + + String operator() default "="; + + boolean ignore() default false; + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/api/CoatingRepository.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/api/CoatingRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..b640e49c9a318912b40eec4e025f06e56daedcdd --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/api/CoatingRepository.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.api; + +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.executor.Page; + +import java.util.List; + +public interface CoatingRepository { + + List selectByCoating(BoundedContext boundedContext, Object coatingObject); + + Page selectPageByCoating(BoundedContext boundedContext, Object coatingObject); + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/api/ExampleBuilder.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/api/ExampleBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..67cbd3db80e77ca591d00baf1250d3680ed037e6 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/api/ExampleBuilder.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.api; + +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.executor.Example; + +public interface ExampleBuilder { + + Example buildExample(BoundedContext boundedContext, Object coatingObject); + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/CoatingWrapper.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/CoatingWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..1610f686d38fb724f4d82862e8cfd9ff0cd8114f --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/CoatingWrapper.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.entity; + +import com.gitee.dorive.coating.entity.definition.CoatingDefinition; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@Data +@AllArgsConstructor +public class CoatingWrapper { + private CoatingDefinition coatingDefinition; + private List repositoryWrappers; + private List reversedRepositoryWrappers; + private SpecificProperties specificProperties; +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/MergedRepository.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/MergedRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..01fcf19422785049c24ac0b965fc7a77fd9fd763 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/MergedRepository.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.entity; + +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class MergedRepository { + private String lastAccessPath; + private String absoluteAccessPath; + private boolean merged; + private ConfiguredRepository definedRepository; + private ConfiguredRepository configuredRepository; +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/PropertyWrapper.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/PropertyWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..2254e0c129ecdf8d8d4e7e0a2706c676aa57d0e7 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/PropertyWrapper.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.entity; + +import com.gitee.dorive.coating.entity.definition.PropertyDefinition; +import com.gitee.dorive.core.entity.Property; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class PropertyWrapper { + private Property property; + private PropertyDefinition propertyDefinition; +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/RepositoryWrapper.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/RepositoryWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..8e1d0c6b2231e0566ea3c9e5ceae5a0300409b94 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/RepositoryWrapper.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.entity; + +import com.gitee.dorive.coating.entity.definition.PropertyDefinition; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.Property; +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.entity.executor.Criterion; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.impl.binder.ContextBinder; +import com.gitee.dorive.core.impl.resolver.BinderResolver; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@Data +@AllArgsConstructor +public class RepositoryWrapper { + + private MergedRepository mergedRepository; + private List collectedPropertyWrappers; + + public Example newExampleByCoating(BoundedContext boundedContext, Object coatingObject) { + Example example = new Example(); + for (PropertyWrapper propertyWrapper : collectedPropertyWrappers) { + Property property = propertyWrapper.getProperty(); + Object fieldValue = property.getFieldValue(coatingObject); + if (fieldValue != null) { + PropertyDefinition propertyDefinition = propertyWrapper.getPropertyDefinition(); + String alias = propertyDefinition.getAlias(); + String operator = propertyDefinition.getOperator(); + example.addCriterion(new Criterion(alias, operator, fieldValue)); + } + } + ConfiguredRepository definedRepository = mergedRepository.getDefinedRepository(); + BinderResolver binderResolver = definedRepository.getBinderResolver(); + for (ContextBinder contextBinder : binderResolver.getContextBinders()) { + Object boundValue = contextBinder.getBoundValue(boundedContext, null); + if (boundValue != null) { + BindingDefinition bindingDefinition = contextBinder.getBindingDefinition(); + String alias = bindingDefinition.getAlias(); + example.eq(alias, boundValue); + } + } + return example; + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/SpecificProperties.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/SpecificProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..93256c7afbaa8612ef9d43c8dc354f64a52e9256 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/SpecificProperties.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.gitee.dorive.coating.entity; + +import cn.hutool.core.convert.Convert; +import com.gitee.dorive.core.api.constant.Order; +import com.gitee.dorive.core.entity.executor.OrderBy; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.core.util.StringUtils; +import lombok.Data; + +@Data +public class SpecificProperties { + + private PropertyWrapper orderByAscProperty; + private PropertyWrapper orderByDescProperty; + private PropertyWrapper pageNumProperty; + private PropertyWrapper pageSizeProperty; + + public boolean addProperty(String fieldName, PropertyWrapper propertyWrapper) { + if ("orderByAsc".equals(fieldName)) { + orderByAscProperty = propertyWrapper; + return true; + + } else if ("orderByDesc".equals(fieldName)) { + orderByDescProperty = propertyWrapper; + return true; + + } else if ("pageNum".equals(fieldName)) { + pageNumProperty = propertyWrapper; + return true; + + } else if ("pageSize".equals(fieldName)) { + pageSizeProperty = propertyWrapper; + return true; + } + return false; + } + + public OrderBy getOrderBy(Object coatingObject) { + if (orderByAscProperty != null) { + Object orderByAsc = orderByAscProperty.getProperty().getFieldValue(coatingObject); + if (orderByAsc != null) { + String[] columns = StringUtils.toStringArray(orderByAsc); + if (columns != null && columns.length > 0) { + return new OrderBy(columns, Order.ASC); + } + } + } + if (orderByDescProperty != null) { + Object orderByDesc = orderByDescProperty.getProperty().getFieldValue(coatingObject); + if (orderByDesc != null) { + String[] columns = StringUtils.toStringArray(orderByDesc); + if (columns != null && columns.length > 0) { + return new OrderBy(columns, Order.DESC); + } + } + } + return null; + } + + public Page getPage(Object coatingObject) { + if (pageNumProperty != null && pageSizeProperty != null) { + Object pageNum = pageNumProperty.getProperty().getFieldValue(coatingObject); + Object pageSize = pageSizeProperty.getProperty().getFieldValue(coatingObject); + if (pageNum != null && pageSize != null) { + return new Page<>(Convert.convert(Long.class, pageNum), Convert.convert(Long.class, pageSize)); + } + } + return null; + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/definition/CoatingDefinition.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/definition/CoatingDefinition.java new file mode 100644 index 0000000000000000000000000000000000000000..9b7709bbe6f19a3da9fd6a4df35ab0606936f730 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/definition/CoatingDefinition.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.entity.definition; + +import cn.hutool.core.bean.BeanUtil; +import com.gitee.dorive.coating.annotation.Coating; +import org.springframework.core.annotation.AnnotatedElementUtils; + +import java.lang.reflect.AnnotatedElement; +import java.util.Map; + +public class CoatingDefinition { + + public static CoatingDefinition newCoatingDefinition(AnnotatedElement annotatedElement) { + Map annotationAttributes = AnnotatedElementUtils.getMergedAnnotationAttributes(annotatedElement, Coating.class); + return BeanUtil.copyProperties(annotationAttributes, CoatingDefinition.class); + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/definition/PropertyDefinition.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/definition/PropertyDefinition.java new file mode 100644 index 0000000000000000000000000000000000000000..364726bbe75d315f25f42299f36268e0a5266f3c --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/entity/definition/PropertyDefinition.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.entity.definition; + +import cn.hutool.core.bean.BeanUtil; +import com.gitee.dorive.coating.annotation.Property; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotatedElementUtils; + +import java.lang.reflect.AnnotatedElement; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PropertyDefinition { + + private String accessPath; + private String alias; + private String operator; + private boolean ignore; + + public static PropertyDefinition newPropertyDefinition(AnnotatedElement annotatedElement) { + Map annotationAttributes = AnnotatedElementUtils.getMergedAnnotationAttributes(annotatedElement, Property.class); + if (annotationAttributes == null) { + return new PropertyDefinition("", "", "=", false); + } + return BeanUtil.copyProperties(annotationAttributes, PropertyDefinition.class); + } + + public static void renewPropertyDefinition(String fieldName, PropertyDefinition propertyDefinition) { + if (StringUtils.isBlank(propertyDefinition.getAlias())) { + propertyDefinition.setAlias(fieldName); + } + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/DefaultExampleBuilder.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/DefaultExampleBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..22e969e8bf01ea79b176b02530eb98055bfbadb5 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/DefaultExampleBuilder.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.impl; + +import cn.hutool.core.lang.Assert; +import com.gitee.dorive.coating.api.ExampleBuilder; +import com.gitee.dorive.coating.entity.CoatingWrapper; +import com.gitee.dorive.coating.entity.MergedRepository; +import com.gitee.dorive.coating.entity.RepositoryWrapper; +import com.gitee.dorive.coating.impl.resolver.CoatingWrapperResolver; +import com.gitee.dorive.coating.repository.AbstractCoatingRepository; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.impl.binder.PropertyBinder; +import com.gitee.dorive.core.impl.resolver.BinderResolver; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.*; + +public class DefaultExampleBuilder implements ExampleBuilder { + + private final AbstractCoatingRepository repository; + + public DefaultExampleBuilder(AbstractCoatingRepository repository) { + this.repository = repository; + } + + @Override + public Example buildExample(BoundedContext boundedContext, Object coatingObject) { + CoatingWrapperResolver coatingWrapperResolver = repository.getCoatingWrapperResolver(); + Map, CoatingWrapper> coatingWrapperMap = coatingWrapperResolver.getCoatingWrapperMap(); + + CoatingWrapper coatingWrapper = coatingWrapperMap.get(coatingObject.getClass()); + Assert.notNull(coatingWrapper, "No coating wrapper exists!"); + + Map repoCriterionMap = new LinkedHashMap<>(); + for (RepositoryWrapper repositoryWrapper : coatingWrapper.getReversedRepositoryWrappers()) { + Example example = repositoryWrapper.newExampleByCoating(boundedContext, coatingObject); + RepoCriterion repoCriterion = new RepoCriterion(repositoryWrapper, example); + + MergedRepository mergedRepository = repositoryWrapper.getMergedRepository(); + String absoluteAccessPath = mergedRepository.getAbsoluteAccessPath(); + String relativeAccessPath = mergedRepository.isMerged() ? absoluteAccessPath + "/" : absoluteAccessPath; + repoCriterionMap.put(relativeAccessPath, repoCriterion); + } + + executeChainQuery(boundedContext, repoCriterionMap); + + RepoCriterion repoCriterion = repoCriterionMap.get("/"); + Assert.notNull(repoCriterion, "The criterion cannot be null!"); + return repoCriterion.getExample(); + } + + private void executeChainQuery(BoundedContext boundedContext, Map repoCriterionMap) { + repoCriterionMap.forEach((accessPath, repoCriterion) -> { + if ("/".equals(accessPath)) return; + + RepositoryWrapper repositoryWrapper = repoCriterion.getRepositoryWrapper(); + Example example = repoCriterion.getExample(); + + MergedRepository mergedRepository = repositoryWrapper.getMergedRepository(); + String lastAccessPath = mergedRepository.getLastAccessPath(); + ConfiguredRepository definedRepository = mergedRepository.getDefinedRepository(); + ConfiguredRepository configuredRepository = mergedRepository.getConfiguredRepository(); + + BinderResolver binderResolver = definedRepository.getBinderResolver(); + + for (PropertyBinder propertyBinder : binderResolver.getPropertyBinders()) { + String absoluteAccessPath = lastAccessPath + propertyBinder.getBelongAccessPath(); + RepoCriterion targetRepoCriterion = repoCriterionMap.get(absoluteAccessPath); + if (targetRepoCriterion != null) { + Example targetExample = targetRepoCriterion.getExample(); + if (targetExample.isEmptyQuery()) { + example.setEmptyQuery(true); + break; + } + } + } + + if (example.isQueryAll()) { + return; + } + + List entities = Collections.emptyList(); + if (!example.isEmptyQuery() && example.isDirtyQuery()) { + example.setSelectColumns(binderResolver.getBoundColumns()); + entities = configuredRepository.selectByExample(boundedContext, example); + } + + for (PropertyBinder propertyBinder : binderResolver.getPropertyBinders()) { + String absoluteAccessPath = lastAccessPath + propertyBinder.getBelongAccessPath(); + RepoCriterion targetRepoCriterion = repoCriterionMap.get(absoluteAccessPath); + if (targetRepoCriterion != null) { + Example targetExample = targetRepoCriterion.getExample(); + if (entities.isEmpty()) { + targetExample.setEmptyQuery(true); + continue; + } + + List fieldValues = collectFieldValues(boundedContext, entities, propertyBinder); + if (fieldValues.isEmpty()) { + targetExample.setEmptyQuery(true); + continue; + } + + BindingDefinition bindingDefinition = propertyBinder.getBindingDefinition(); + String bindAlias = bindingDefinition.getBindAlias(); + Object fieldValue = fieldValues.size() == 1 ? fieldValues.get(0) : fieldValues; + fieldValue = propertyBinder.output(boundedContext, fieldValue); + targetExample.eq(bindAlias, fieldValue); + } + } + }); + } + + private List collectFieldValues(BoundedContext boundedContext, List entities, PropertyBinder propertyBinder) { + List fieldValues = new ArrayList<>(); + for (Object entity : entities) { + Object fieldValue = propertyBinder.getFieldValue(boundedContext, entity); + if (fieldValue != null) { + fieldValues.add(fieldValue); + } + } + return fieldValues; + } + + @Data + @AllArgsConstructor + public static class RepoCriterion { + private RepositoryWrapper repositoryWrapper; + private Example example; + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/resolver/CoatingWrapperResolver.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/resolver/CoatingWrapperResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..19d4cdc24855e8f8ba042f091f737d9dd2c9968a --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/resolver/CoatingWrapperResolver.java @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.impl.resolver; + +import com.gitee.dorive.coating.annotation.Coating; +import com.gitee.dorive.coating.entity.CoatingWrapper; +import com.gitee.dorive.coating.entity.MergedRepository; +import com.gitee.dorive.coating.entity.PropertyWrapper; +import com.gitee.dorive.coating.entity.RepositoryWrapper; +import com.gitee.dorive.coating.entity.SpecificProperties; +import com.gitee.dorive.coating.repository.AbstractCoatingRepository; +import com.gitee.dorive.coating.entity.definition.CoatingDefinition; +import com.gitee.dorive.coating.entity.definition.PropertyDefinition; +import com.gitee.dorive.coating.util.ResourceUtils; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.Property; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.ReflectionUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Data +public class CoatingWrapperResolver { + + private AbstractCoatingRepository repository; + + private Map, CoatingWrapper> coatingWrapperMap = new ConcurrentHashMap<>(); + + public CoatingWrapperResolver(AbstractCoatingRepository repository) { + this.repository = repository; + } + + public void resolveCoatingWrapperMap(String... scanPackages) throws Exception { + for (String scanPackage : scanPackages) { + List> classes = ResourceUtils.resolveClasses(scanPackage); + for (Class coatingClass : classes) { + + Coating coatingAnnotation = AnnotationUtils.getAnnotation(coatingClass, Coating.class); + if (coatingAnnotation == null) { + continue; + } + if (coatingAnnotation.qualifier() != Object.class && coatingAnnotation.qualifier() != repository.getEntityClass()) { + continue; + } + + Set fieldNames = new LinkedHashSet<>(); + Map> accessPathPropertyWrappersMap = new LinkedHashMap<>(); + Map fieldPropertyWrapperMap = new LinkedHashMap<>(); + SpecificProperties specificProperties = new SpecificProperties(); + + ReflectionUtils.doWithLocalFields(coatingClass, declaredField -> { + Property property = new Property(declaredField); + String fieldName = property.getFieldName(); + + PropertyDefinition propertyDefinition = PropertyDefinition.newPropertyDefinition(declaredField); + PropertyDefinition.renewPropertyDefinition(fieldName, propertyDefinition); + if (propertyDefinition.isIgnore()) { + return; + } + + PropertyWrapper propertyWrapper = new PropertyWrapper(property, propertyDefinition); + if (specificProperties.addProperty(fieldName, propertyWrapper)) { + return; + } + + fieldNames.add(fieldName); + + String accessPath = propertyDefinition.getAccessPath(); + if (StringUtils.isNotBlank(accessPath) && accessPath.startsWith("/")) { + List existPropertyWrappers = accessPathPropertyWrappersMap.computeIfAbsent(accessPath, key -> new ArrayList<>()); + existPropertyWrappers.add(propertyWrapper); + } else { + fieldPropertyWrapperMap.put(fieldName, propertyWrapper); + } + }); + + List repositoryWrappers = collectRepositoryWrappers(accessPathPropertyWrappersMap, fieldPropertyWrapperMap); + checkFieldNames(coatingClass, fieldNames, repositoryWrappers); + + List reversedRepositoryWrappers = new ArrayList<>(repositoryWrappers); + Collections.reverse(reversedRepositoryWrappers); + + CoatingDefinition coatingDefinition = CoatingDefinition.newCoatingDefinition(coatingClass); + CoatingWrapper coatingWrapper = new CoatingWrapper(coatingDefinition, repositoryWrappers, reversedRepositoryWrappers, specificProperties); + coatingWrapperMap.put(coatingClass, coatingWrapper); + } + } + } + + private List collectRepositoryWrappers(Map> accessPathPropertyWrappersMap, + Map fieldPropertyWrapperMap) { + MergedRepositoryResolver mergedRepositoryResolver = repository.getMergedRepositoryResolver(); + Map mergedRepositoryMap = mergedRepositoryResolver.getMergedRepositoryMap(); + + List repositoryWrappers = new ArrayList<>(); + + for (MergedRepository mergedRepository : mergedRepositoryMap.values()) { + String absoluteAccessPath = mergedRepository.getAbsoluteAccessPath(); + ConfiguredRepository repository = mergedRepository.getConfiguredRepository(); + EntityElement entityElement = repository.getEntityElement(); + + List propertyWrappers = new ArrayList<>(); + + List accessPathPropertyWrappers = accessPathPropertyWrappersMap.get(absoluteAccessPath); + if (accessPathPropertyWrappers != null) { + propertyWrappers.addAll(accessPathPropertyWrappers); + } + + for (String fieldName : entityElement.getProperties()) { + PropertyWrapper propertyWrapper = fieldPropertyWrapperMap.get(fieldName); + if (propertyWrapper != null) { + propertyWrappers.add(propertyWrapper); + } + } + + if (!propertyWrappers.isEmpty() || repository.isBoundEntity()) { + RepositoryWrapper repositoryWrapper = new RepositoryWrapper(mergedRepository, propertyWrappers); + repositoryWrappers.add(repositoryWrapper); + } + } + + return repositoryWrappers; + } + + private void checkFieldNames(Class coatingClass, Set fieldNames, List repositoryWrappers) { + Set remainFieldNames = new LinkedHashSet<>(fieldNames); + for (RepositoryWrapper repositoryWrapper : repositoryWrappers) { + for (PropertyWrapper propertyWrapper : repositoryWrapper.getCollectedPropertyWrappers()) { + remainFieldNames.remove(propertyWrapper.getProperty().getFieldName()); + } + } + if (!remainFieldNames.isEmpty()) { + String errorMessage = String.format("The field does not exist in the aggregate root! entity: %s, coating: %s, fieldNames: %s", + repository.getEntityClass(), coatingClass, remainFieldNames); + throw new RuntimeException(errorMessage); + } + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/resolver/MergedRepositoryResolver.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/resolver/MergedRepositoryResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..195bb350e7af50b803f4671de8c8bed677b133ac --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/impl/resolver/MergedRepositoryResolver.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.impl.resolver; + +import cn.hutool.core.util.StrUtil; +import com.gitee.dorive.coating.entity.MergedRepository; +import com.gitee.dorive.core.repository.AbstractContextRepository; +import com.gitee.dorive.core.repository.AbstractRepository; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.Data; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Data +public class MergedRepositoryResolver { + + private AbstractContextRepository repository; + + private Map mergedRepositoryMap = new LinkedHashMap<>(); + + public MergedRepositoryResolver(AbstractContextRepository repository) { + this.repository = repository; + } + + public void resolveMergedRepositoryMap() { + ConfiguredRepository rootRepository = repository.getRootRepository(); + MergedRepository mergedRepository = new MergedRepository( + "", + "/", + false, + rootRepository, + rootRepository); + mergedRepositoryMap.put("/", mergedRepository); + resolveMergedRepositoryMap(new ArrayList<>(), repository); + } + + private void resolveMergedRepositoryMap(List multiAccessPath, AbstractContextRepository lastRepository) { + String lastAccessPath = StrUtil.join("", multiAccessPath); + + for (ConfiguredRepository repository : lastRepository.getSubRepositories()) { + String accessPath = repository.getAccessPath(); + String absoluteAccessPath = lastAccessPath + accessPath; + AbstractRepository abstractRepository = repository.getProxyRepository(); + + if (abstractRepository instanceof AbstractContextRepository) { + AbstractContextRepository abstractContextRepository = (AbstractContextRepository) abstractRepository; + ConfiguredRepository rootRepository = abstractContextRepository.getRootRepository(); + + MergedRepository mergedRepository = new MergedRepository( + lastAccessPath, + absoluteAccessPath, + true, + repository, + rootRepository); + mergedRepositoryMap.put(absoluteAccessPath, mergedRepository); + + List newMultiAccessPath = new ArrayList<>(multiAccessPath); + newMultiAccessPath.add(accessPath); + resolveMergedRepositoryMap(newMultiAccessPath, abstractContextRepository); + + } else { + MergedRepository mergedRepository = new MergedRepository( + lastAccessPath, + absoluteAccessPath, + false, + repository, + repository); + mergedRepositoryMap.put(absoluteAccessPath, mergedRepository); + } + } + } + +} diff --git a/dorive-coating/src/main/java/com/gitee/dorive/coating/repository/AbstractCoatingRepository.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/repository/AbstractCoatingRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..46d46cfec734ddc43cd506c8d758508897bba169 --- /dev/null +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/repository/AbstractCoatingRepository.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.repository; + +import com.gitee.dorive.coating.annotation.CoatingScan; +import com.gitee.dorive.coating.api.CoatingRepository; +import com.gitee.dorive.coating.api.ExampleBuilder; +import com.gitee.dorive.coating.impl.resolver.CoatingWrapperResolver; +import com.gitee.dorive.coating.impl.DefaultExampleBuilder; +import com.gitee.dorive.coating.impl.resolver.MergedRepositoryResolver; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.event.repository.AbstractEventRepository; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.core.annotation.AnnotatedElementUtils; + +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = false) +public abstract class AbstractCoatingRepository extends AbstractEventRepository implements ExampleBuilder, CoatingRepository { + + protected MergedRepositoryResolver mergedRepositoryResolver = new MergedRepositoryResolver(this); + protected CoatingWrapperResolver coatingWrapperResolver = new CoatingWrapperResolver(this); + protected ExampleBuilder exampleBuilder = new DefaultExampleBuilder(this); + + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + CoatingScan coatingScan = AnnotatedElementUtils.getMergedAnnotation(this.getClass(), CoatingScan.class); + if (coatingScan != null) { + mergedRepositoryResolver.resolveMergedRepositoryMap(); + coatingWrapperResolver.resolveCoatingWrapperMap(coatingScan.value()); + } + } + + @Override + public Example buildExample(BoundedContext boundedContext, Object coatingObject) { + return exampleBuilder.buildExample(boundedContext, coatingObject); + } + + @Override + public List selectByCoating(BoundedContext boundedContext, Object coatingObject) { + Example example = buildExample(boundedContext, coatingObject); + return selectByExample(boundedContext, example); + } + + @Override + public Page selectPageByCoating(BoundedContext boundedContext, Object coatingObject) { + Example example = buildExample(boundedContext, coatingObject); + return selectPageByExample(boundedContext, example); + } + +} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/utils/ResourceUtils.java b/dorive-coating/src/main/java/com/gitee/dorive/coating/util/ResourceUtils.java similarity index 64% rename from spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/utils/ResourceUtils.java rename to dorive-coating/src/main/java/com/gitee/dorive/coating/util/ResourceUtils.java index df02a950adcd8f25a5de6093fcc483f4386706bc..2011070a4c53302afe6e7c063817fbed24eff111 100644 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/utils/ResourceUtils.java +++ b/dorive-coating/src/main/java/com/gitee/dorive/coating/util/ResourceUtils.java @@ -1,4 +1,20 @@ -package com.gitee.spring.domain.coating.utils; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.coating.util; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; diff --git a/spring-domain-core/pom.xml b/dorive-core/pom.xml similarity index 71% rename from spring-domain-core/pom.xml rename to dorive-core/pom.xml index c8aa135485452fb24d2e3c4bb134b0f476c6fbb4..5d481184e435437453c49c9940844aa05c998448 100644 --- a/spring-domain-core/pom.xml +++ b/dorive-core/pom.xml @@ -5,12 +5,16 @@ 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 - spring-domain-core - + dorive-core + + com.gitee.digital-engine + dorive-proxy + ${project.version} + org.springframework.boot spring-boot-starter-web @@ -19,17 +23,9 @@ org.projectlombok lombok - - org.apache.commons - commons-lang3 - cn.hutool hutool-all - - org.javassist - javassist - \ No newline at end of file diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Binding.java b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Binding.java new file mode 100644 index 0000000000000000000000000000000000000000..6054689284c2ce04debe57eea4ec8b399cebbe70 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Binding.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.annotation; + +import com.gitee.dorive.core.impl.processor.DefaultProcessor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Documented +@Repeatable(Bindings.class) +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface Binding { + + String field(); + + String bindProp() default ""; + + String property() default ""; + + Class processor() default DefaultProcessor.class; + + String bindCtx() default ""; + + String alias() default ""; + + String bindAlias() default ""; + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Bindings.java b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Bindings.java new file mode 100644 index 0000000000000000000000000000000000000000..9ae8e3afcce23779b0ed0799ada33f9e7c88942b --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Bindings.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.annotation; + +import java.lang.annotation.*; + +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface Bindings { + Binding[] value(); +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Entity.java b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Entity.java new file mode 100644 index 0000000000000000000000000000000000000000..5923273d41308f089b007af7ceaa6164837352f8 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Entity.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.annotation; + +import com.gitee.dorive.core.repository.DefaultRepository; +import com.gitee.dorive.core.impl.DefaultEntityFactory; + +import java.lang.annotation.*; + +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface Entity { + + String[] matchKeys() default {}; + + int order() default 0; + + Class mapper() default Object.class; + + Class factory() default DefaultEntityFactory.class; + + Class repository() default DefaultRepository.class; + + String orderByAsc() default ""; + + String orderByDesc() default ""; + + String builderKey() default ""; + + String commandKey() default ""; + +} + diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Repository.java b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Repository.java new file mode 100644 index 0000000000000000000000000000000000000000..0f093853d5c70cd7a1d6a4f51f3089ed6ebc8dc2 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/annotation/Repository.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.annotation; + +import org.springframework.core.annotation.AliasFor; +import org.springframework.stereotype.Component; + +import java.lang.annotation.*; + +@Component +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Repository { + + @AliasFor(annotation = Component.class) + String value() default ""; + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/Binder.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/Binder.java new file mode 100644 index 0000000000000000000000000000000000000000..8fe93b25fe1203abc2ef4c5c164aae85e4d753b7 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/Binder.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.definition.BindingDefinition; + +public interface Binder { + + BindingDefinition getBindingDefinition(); + + Object getFieldValue(BoundedContext boundedContext, Object entity); + + void setFieldValue(BoundedContext boundedContext, Object entity, Object property); + + Object getBoundValue(BoundedContext boundedContext, Object rootEntity); + + void setBoundValue(BoundedContext boundedContext, Object rootEntity, Object property); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityFactory.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..59425b7a939b3d1eb5dd4812ee24d9e76785196a --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityFactory.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; + +public interface EntityFactory { + + Object reconstitute(BoundedContext boundedContext, Object persistentObject); + + Object deconstruct(BoundedContext boundedContext, Object entity); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityHandler.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..26fa3a01bbeadbffe98de8b8ac534b13557b3bf0 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityHandler.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; + +import java.util.List; + +public interface EntityHandler { + + void handleEntities(BoundedContext boundedContext, List rootEntities); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityIndex.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityIndex.java new file mode 100644 index 0000000000000000000000000000000000000000..bb0ad328ce8a79baebe3e97e2659112cfca6bd3d --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/EntityIndex.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import java.util.List; + +public interface EntityIndex { + + List selectList(Object rootEntity, Object primaryKey); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/ExampleBuilder.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/ExampleBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..1fd1a007716b7f3e18d4b99d91d1d37be4ff6773 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/ExampleBuilder.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.executor.Example; + +public interface ExampleBuilder { + + Example buildExample(BoundedContext boundedContext, Object rootEntity, Example example); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/Executor.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/Executor.java new file mode 100644 index 0000000000000000000000000000000000000000..8f0aa584e9c00c386fa338820892a728fcb48122 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/Executor.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.operation.Delete; +import com.gitee.dorive.core.entity.operation.Insert; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.entity.operation.Query; +import com.gitee.dorive.core.entity.operation.Update; + +public interface Executor { + + Query buildQueryByPK(BoundedContext boundedContext, Object primaryKey); + + Query buildQuery(BoundedContext boundedContext, Example example); + + Result executeQuery(BoundedContext boundedContext, Query query); + + Insert buildInsert(BoundedContext boundedContext, Object entity); + + Update buildUpdate(BoundedContext boundedContext, Object entity); + + Update buildUpdate(BoundedContext boundedContext, Object entity, Example example); + + Operation buildInsertOrUpdate(BoundedContext boundedContext, Object entity); + + Delete buildDelete(BoundedContext boundedContext, Object entity); + + Delete buildDeleteByPK(BoundedContext boundedContext, Object primaryKey); + + Delete buildDelete(BoundedContext boundedContext, Example example); + + int execute(BoundedContext boundedContext, Operation operation); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/ListableRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/ListableRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..111a4f65bc0011717a63616184af2c3d1d0ec607 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/ListableRepository.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; + +import java.util.List; + +public interface ListableRepository extends Repository { + + int insertList(BoundedContext boundedContext, List entities); + + int updateList(BoundedContext boundedContext, List entities); + + int insertOrUpdateList(BoundedContext boundedContext, List entities); + + int deleteList(BoundedContext boundedContext, List entities); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/MetadataHolder.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/MetadataHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..390c408b154fa9eb403c5a530f47f4e98b15e30e --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/MetadataHolder.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +public interface MetadataHolder { + + Object getMetadata(); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/Processor.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/Processor.java new file mode 100644 index 0000000000000000000000000000000000000000..5303647756d31275094201521b48d4d3e34ba7fe --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/Processor.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.BoundedContext; + +public interface Processor { + + Object input(BoundedContext boundedContext, Object valueObject); + + Object output(BoundedContext boundedContext, Object valueObject); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/PropertyProxy.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/PropertyProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..382926bfef9fd91590038ffd7199514771a4f924 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/PropertyProxy.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +public interface PropertyProxy { + + Object getValue(Object entity); + + void setValue(Object entity, Object value); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/Repository.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/Repository.java new file mode 100644 index 0000000000000000000000000000000000000000..df1d74d3252856f41ddb5a3a1d7eba91cf2e7d42 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/Repository.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api; + +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.BoundedContext; + +import java.util.List; + +/** + * 仓储接口 + * + * @param 实体类型 + * @param 主键类型 + */ +public interface Repository { + + /** + * 根据主键查询实体 + * + * @param boundedContext 边界上下文 + * @param primaryKey 主键 + * @return 实体 + */ + E selectByPrimaryKey(BoundedContext boundedContext, PK primaryKey); + + /** + * 根据条件查询实体 + * + * @param boundedContext 边界上下文 + * @param example 条件 + * @return 实体 + */ + List selectByExample(BoundedContext boundedContext, Example example); + + /** + * 根据条件查询分页 + * + * @param boundedContext 边界上下文 + * @param example 条件 + * @return 分页 + */ + Page selectPageByExample(BoundedContext boundedContext, Example example); + + /** + * 根据条件查询结果集 + * + * @param boundedContext 边界上下文 + * @param example 条件 + * @return 结果集 + */ + Result selectResultByExample(BoundedContext boundedContext, Example example); + + /** + * 插入一个实体 + * + * @param boundedContext 边界上下文 + * @param entity 实体 + * @return 操作数 + */ + int insert(BoundedContext boundedContext, E entity); + + /** + * 根据实体的主键,修改一个实体 + * + * @param boundedContext 边界上下文 + * @param entity 实体 + * @return 操作数 + */ + int update(BoundedContext boundedContext, E entity); + + /** + * 根据实体和条件,修改聚合内的所有实体 + * + * @param boundedContext 边界上下文 + * @param entity 实体 + * @param example 条件 + * @return 操作数 + */ + int updateByExample(BoundedContext boundedContext, Object entity, Example example); + + /** + * 根据实体的主键,插入或者修改一个实体。 + * 主键为空则插入,主键不为空则修改。 + * + * @param boundedContext 边界上下文 + * @param entity 实体 + * @return 操作数 + */ + int insertOrUpdate(BoundedContext boundedContext, E entity); + + /** + * 根据实体的主键,删除一个实体 + * + * @param boundedContext 边界上下文 + * @param entity 实体 + * @return 操作数 + */ + int delete(BoundedContext boundedContext, E entity); + + /** + * 根据主键,删除一个实体 + * + * @param boundedContext 边界上下文 + * @param primaryKey 主键 + * @return 操作数 + */ + int deleteByPrimaryKey(BoundedContext boundedContext, PK primaryKey); + + /** + * 根据条件,删除聚合内的所有实体 + * + * @param boundedContext 边界上下文 + * @param example 条件 + * @return 操作数 + */ + int deleteByExample(BoundedContext boundedContext, Example example); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/constant/Operator.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/constant/Operator.java new file mode 100644 index 0000000000000000000000000000000000000000..4fbc6dc12f3c18c216208098c675696b269476c2 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/constant/Operator.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api.constant; + +public interface Operator { + String EQ = "="; + String NE = "<>"; + String IN = "IN"; + String NOT_IN = "NOT IN"; + String IS = "IS"; + String IS_NOT = "IS NOT"; + String LIKE = "LIKE"; + String NOT_LIKE = "NOT LIKE"; + String GT = ">"; + String GE = ">="; + String LT = "<"; + String LE = "<="; +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/api/constant/Order.java b/dorive-core/src/main/java/com/gitee/dorive/core/api/constant/Order.java new file mode 100644 index 0000000000000000000000000000000000000000..d94ddd77c0e75d11aa7e79024c62db64b3666814 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/api/constant/Order.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.api.constant; + +public interface Order { + String ASC = "ASC"; + String DESC = "DESC"; +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/config/DomainCoreConfiguration.java b/dorive-core/src/main/java/com/gitee/dorive/core/config/DomainCoreConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..fec5500861acadcfcff44ba74933f1bf430c9b9f --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/config/DomainCoreConfiguration.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +@Order(-100) +@Configuration +public class DomainCoreConfiguration { + + @Bean + public RepositoryContext repositoryContext() { + return new RepositoryContext(); + } + +} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/config/RepositoryContext.java b/dorive-core/src/main/java/com/gitee/dorive/core/config/RepositoryContext.java similarity index 40% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/config/RepositoryContext.java rename to dorive-core/src/main/java/com/gitee/dorive/core/config/RepositoryContext.java index 29a513cf7ab7812d1b8581a48176960cbb7c375f..fc2793605fa76c25004e43eb649850e6c7f409ec 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/config/RepositoryContext.java +++ b/dorive-core/src/main/java/com/gitee/dorive/core/config/RepositoryContext.java @@ -1,6 +1,22 @@ -package com.gitee.spring.domain.core.config; - -import com.gitee.spring.domain.core.repository.AbstractGenericRepository; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.config; + +import com.gitee.dorive.core.repository.AbstractContextRepository; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; @@ -11,9 +27,10 @@ import java.util.concurrent.ConcurrentHashMap; public class RepositoryContext implements ApplicationContextAware, InitializingBean { - private static final Map, AbstractGenericRepository> CLASS_REPOSITORY_MAP = new ConcurrentHashMap<>(); private ApplicationContext applicationContext; + private static final Map, AbstractContextRepository> CLASS_REPOSITORY_MAP = new ConcurrentHashMap<>(); + @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; @@ -22,14 +39,14 @@ public class RepositoryContext implements ApplicationContextAware, InitializingB @Override @SuppressWarnings("rawtypes") public void afterPropertiesSet() { - Map beansOfType = applicationContext.getBeansOfType(AbstractGenericRepository.class); - for (AbstractGenericRepository abstractGenericRepository : beansOfType.values()) { - CLASS_REPOSITORY_MAP.put(abstractGenericRepository.getEntityClass(), abstractGenericRepository); + Map beansOfType = applicationContext.getBeansOfType(AbstractContextRepository.class); + for (AbstractContextRepository repository : beansOfType.values()) { + CLASS_REPOSITORY_MAP.put(repository.getEntityClass(), repository); } } @SuppressWarnings("unchecked") - public static , E> R getRepository(Class entityClass) { + public static , E> R getRepository(Class entityClass) { return (R) CLASS_REPOSITORY_MAP.get(entityClass); } diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/BoundedContext.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/BoundedContext.java new file mode 100644 index 0000000000000000000000000000000000000000..48a151d70c88bfe54601b42a66462a911856c5ef --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/BoundedContext.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity; + +import com.gitee.dorive.core.api.ExampleBuilder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.LinkedHashMap; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class BoundedContext extends LinkedHashMap { + + public BoundedContext(String... keys) { + putKeys(keys); + } + + public void putKeys(String... keys) { + for (String key : keys) { + put(key, true); + } + } + + public void putBuilder(String key, ExampleBuilder builder) { + put(key, builder); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/Command.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/Command.java new file mode 100644 index 0000000000000000000000000000000000000000..7fce8303a480e84c869ccf809af811fba869eae6 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/Command.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity; + +import lombok.Data; + +import java.util.Set; + +@Data +public class Command { + private boolean forceIgnore; + private boolean forceInsert; + private Set nullableProperties; +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/EntityElement.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/EntityElement.java new file mode 100644 index 0000000000000000000000000000000000000000..be9d213a85ebcf5c8a1a94bc028987cbd08d109d --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/EntityElement.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity; + +import cn.hutool.core.lang.Assert; +import com.gitee.dorive.core.annotation.Binding; +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.core.impl.PropertyProxyFactory; +import com.gitee.dorive.core.util.ReflectUtils; +import com.gitee.dorive.core.annotation.Entity; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.core.annotation.AnnotatedElementUtils; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Field; +import java.util.Set; + +@Data +@AllArgsConstructor +public class EntityElement { + + private Entity entityAnnotation; + private Set bindingAnnotations; + private AnnotatedElement annotatedElement; + private Class entityClass; + private boolean collection; + private Class genericEntityClass; + private String fieldName; + private Set properties; + private PropertyProxy primaryKeyProxy; + + public static EntityElement newEntityElement(AnnotatedElement annotatedElement) { + Entity entityAnnotation = AnnotatedElementUtils.getMergedAnnotation(annotatedElement, Entity.class); + Assert.notNull(entityAnnotation, "The annotation @Entity cannot be null!"); + Set bindingAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations(annotatedElement, Binding.class); + + if (annotatedElement instanceof Class) { + Class entityClass = (Class) annotatedElement; + return new EntityElement( + entityAnnotation, + bindingAnnotations, + annotatedElement, + entityClass, + false, + entityClass, + null, + ReflectUtils.getFieldNames(entityClass), + PropertyProxyFactory.newPropertyProxy(entityClass, "id")); + + } else if (annotatedElement instanceof Field) { + Property property = new Property((Field) annotatedElement); + return new EntityElement( + entityAnnotation, + bindingAnnotations, + annotatedElement, + property.getFieldClass(), + property.isCollection(), + property.getGenericFieldClass(), + property.getFieldName(), + ReflectUtils.getFieldNames(property.getGenericFieldClass()), + PropertyProxyFactory.newPropertyProxy(property.getGenericFieldClass(), "id")); + + } else { + throw new RuntimeException("Unknown type!"); + } + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/Property.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/Property.java new file mode 100644 index 0000000000000000000000000000000000000000..0372caea2a01e5f1256d14ec679ba742f3efecfd --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/Property.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity; + +import cn.hutool.core.util.ReflectUtil; +import lombok.Data; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collection; + +@Data +public class Property { + + private Field declaredField; + private Class fieldClass; + private boolean collection; + private Class genericFieldClass; + private String fieldName; + + public Property(Field declaredField) { + Class fieldClass = declaredField.getType(); + boolean isCollection = false; + Class fieldGenericClass = fieldClass; + String fieldName = declaredField.getName(); + + if (Collection.class.isAssignableFrom(fieldClass)) { + isCollection = true; + ParameterizedType parameterizedType = (ParameterizedType) declaredField.getGenericType(); + Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; + fieldGenericClass = (Class) actualTypeArgument; + } + + this.declaredField = declaredField; + this.fieldClass = fieldClass; + this.collection = isCollection; + this.genericFieldClass = fieldGenericClass; + this.fieldName = fieldName; + } + + public boolean isSameType(Property property) { + return fieldClass == property.getFieldClass() && genericFieldClass == property.getGenericFieldClass(); + } + + public Object getFieldValue(Object object) { + return ReflectUtil.getFieldValue(object, declaredField); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/PropertyChain.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/PropertyChain.java new file mode 100644 index 0000000000000000000000000000000000000000..9dfec7332aba8a71b8444a4f8648f6f2b7e3b107 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/PropertyChain.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity; + +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.core.impl.PropertyProxyFactory; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.ToString; + +@Data +@AllArgsConstructor +@ToString(exclude = "lastPropertyChain") +public class PropertyChain implements PropertyProxy { + + private PropertyChain lastPropertyChain; + private Class entityClass; + private String accessPath; + private boolean annotatedEntity; + private Property property; + private PropertyProxy propertyProxy; + + public void initialize() { + if (propertyProxy == null) { + propertyProxy = PropertyProxyFactory.newPropertyProxy(entityClass, property.getDeclaredField()); + if (lastPropertyChain != null) { + lastPropertyChain.initialize(); + } + } + } + + @Override + public Object getValue(Object entity) { + if (lastPropertyChain != null) { + entity = lastPropertyChain.getValue(entity); + } + return entity != null ? propertyProxy.getValue(entity) : null; + } + + @Override + public void setValue(Object entity, Object value) { + if (lastPropertyChain != null) { + entity = lastPropertyChain.getValue(entity); + } + if (entity != null) { + propertyProxy.setValue(entity, value); + } + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/definition/BindingDefinition.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/definition/BindingDefinition.java new file mode 100644 index 0000000000000000000000000000000000000000..31f1940d8d03ba40b87e9a20d76029f25b16afad --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/definition/BindingDefinition.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.definition; + +import cn.hutool.core.bean.BeanUtil; +import com.gitee.dorive.core.annotation.Binding; +import com.gitee.dorive.core.entity.EntityElement; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.core.annotation.AnnotationUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +public class BindingDefinition { + + private String field; + private String bindProp; + private String property; + private Class processor; + private String bindCtx; + private String alias; + private String bindAlias; + + public static List newBindingDefinitions(EntityElement entityElement) { + List bindingDefinitions = new ArrayList<>(); + for (Binding bindingAnnotation : entityElement.getBindingAnnotations()) { + Map annotationAttributes = AnnotationUtils.getAnnotationAttributes(bindingAnnotation); + bindingDefinitions.add(BeanUtil.copyProperties(annotationAttributes, BindingDefinition.class)); + } + return bindingDefinitions; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/definition/EntityDefinition.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/definition/EntityDefinition.java new file mode 100644 index 0000000000000000000000000000000000000000..e7ff3b1589356aa81e2ecc266d1890c238330636 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/definition/EntityDefinition.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.definition; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; +import com.gitee.dorive.core.entity.executor.OrderBy; +import com.gitee.dorive.core.annotation.Entity; +import com.gitee.dorive.core.api.constant.Order; +import com.gitee.dorive.core.entity.EntityElement; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotationUtils; + +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EntityDefinition { + + private String[] matchKeys; + private int order; + private Class mapper; + private Class factory; + private Class repository; + private String orderByAsc; + private String orderByDesc; + private String builderKey; + private String commandKey; + + public static EntityDefinition newEntityDefinition(EntityElement entityElement) { + Entity entityAnnotation = entityElement.getEntityAnnotation(); + Map annotationAttributes = AnnotationUtils.getAnnotationAttributes(entityAnnotation); + return BeanUtil.copyProperties(annotationAttributes, EntityDefinition.class); + } + + public OrderBy getDefaultOrderBy() { + if (StringUtils.isNotBlank(this.orderByAsc)) { + String orderByAsc = StrUtil.toUnderlineCase(this.orderByAsc); + String[] columns = StrUtil.splitTrim(orderByAsc, ",").toArray(new String[0]); + return new OrderBy(columns, Order.ASC); + } + if (StringUtils.isNotBlank(this.orderByDesc)) { + String orderByDesc = StrUtil.toUnderlineCase(this.orderByDesc); + String[] columns = StrUtil.splitTrim(orderByDesc, ",").toArray(new String[0]); + return new OrderBy(columns, Order.DESC); + } + return null; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Criterion.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Criterion.java new file mode 100644 index 0000000000000000000000000000000000000000..582fe9f8b0e6d2a8dceb4a56107b797d7881979c --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Criterion.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.executor; + +import cn.hutool.core.util.StrUtil; +import com.gitee.dorive.core.api.constant.Operator; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.text.SimpleDateFormat; +import java.util.*; + +@Data +@AllArgsConstructor +public class Criterion { + + private static final SimpleDateFormat SQL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + private String property; + private String operator; + private Object value; + + @Override + public String toString() { + String property = StrUtil.toUnderlineCase(this.property); + String operator = this.operator; + if (this.value instanceof Collection) { + if (Operator.EQ.equals(operator)) { + operator = Operator.IN; + + } else if (Operator.NE.equals(operator)) { + operator = Operator.NOT_IN; + } + } + String value = convert(this.value); + return property + " " + operator + " " + value; + } + + private String convert(Object value) { + if (value instanceof Collection) { + Collection collection = (Collection) value; + List values = new ArrayList<>(collection.size()); + for (Object item : collection) { + values.add(doConvert(item)); + } + return "(" + StrUtil.join(", ", values) + ")"; + + } else if (operator.endsWith(Operator.IN)) { + return "(" + doConvert(value) + ")"; + } + return doConvert(value); + } + + private String doConvert(Object value) { + if (value instanceof Number) { + return String.valueOf(value); + + } else if (value instanceof String) { + return "'" + value + "'"; + + } else if (value instanceof Date) { + return "'" + SQL_DATE_FORMAT.format((Date) value) + "'"; + + } else if (value == null || operator.startsWith(Operator.IS)) { + return "NULL"; + } + return value.toString(); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Example.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Example.java new file mode 100644 index 0000000000000000000000000000000000000000..5189a91f7bc23bd957e6efebb0ef831654afb902 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Example.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.executor; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import com.gitee.dorive.core.api.constant.Operator; +import com.gitee.dorive.core.api.constant.Order; +import com.gitee.dorive.core.util.StringUtils; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +public class Example { + + private boolean emptyQuery = false; + private String[] selectColumns; + private List criteria = new ArrayList<>(4); + private OrderBy orderBy; + private Page page; + + public boolean isDirtyQuery() { + return !criteria.isEmpty(); + } + + public boolean isQueryAll() { + return !emptyQuery && !isDirtyQuery(); + } + + public void selectColumns(String... columns) { + selectColumns = selectColumns == null ? columns : ArrayUtil.addAll(selectColumns, columns); + } + + public void addCriterion(Criterion criterion) { + criteria.add(criterion); + } + + public String buildCriteria() { + return StrUtil.join(" AND ", criteria); + } + + public Example eq(String property, Object value) { + criteria.add(new Criterion(property, Operator.EQ, value)); + return this; + } + + public Example ne(String property, Object value) { + criteria.add(new Criterion(property, Operator.NE, value)); + return this; + } + + public Example in(String property, Object value) { + criteria.add(new Criterion(property, Operator.IN, value)); + return this; + } + + public Example notIn(String property, Object value) { + criteria.add(new Criterion(property, Operator.NOT_IN, value)); + return this; + } + + public Example isNull(String property) { + criteria.add(new Criterion(property, Operator.IS, null)); + return this; + } + + public Example isNotNull(String property) { + criteria.add(new Criterion(property, Operator.IS_NOT, null)); + return this; + } + + public Example like(String property, Object value) { + criteria.add(new Criterion(property, Operator.LIKE, value)); + return this; + } + + public Example notLike(String property, Object value) { + criteria.add(new Criterion(property, Operator.NOT_LIKE, value)); + return this; + } + + public Example gt(String property, Object value) { + criteria.add(new Criterion(property, Operator.GT, value)); + return this; + } + + public Example ge(String property, Object value) { + criteria.add(new Criterion(property, Operator.GE, value)); + return this; + } + + public Example lt(String property, Object value) { + criteria.add(new Criterion(property, Operator.LT, value)); + return this; + } + + public Example le(String property, Object value) { + criteria.add(new Criterion(property, Operator.LE, value)); + return this; + } + + public Example orderByAsc(String... columns) { + orderBy = new OrderBy(StringUtils.toUnderlineCase(columns), Order.ASC); + return this; + } + + public Example orderByDesc(String... columns) { + orderBy = new OrderBy(StringUtils.toUnderlineCase(columns), Order.DESC); + return this; + } + + public Example startPage(long pageNum, long pageSize) { + page = new Page<>(pageNum, pageSize); + return this; + } + + public Example startPage() { + page = new Page<>(); + return this; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/OrderBy.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/OrderBy.java new file mode 100644 index 0000000000000000000000000000000000000000..fd961b519f9a0e2e9705c427ec81de6d976a2775 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/OrderBy.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.executor; + +import cn.hutool.core.util.StrUtil; +import com.gitee.dorive.core.util.StringUtils; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class OrderBy { + + private String[] columns; + private String order; + + @Override + public String toString() { + String[] columns = StringUtils.toUnderlineCase(this.columns); + return "ORDER BY " + StrUtil.join(", ", (Object) columns) + " " + order.toUpperCase(); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Page.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Page.java new file mode 100644 index 0000000000000000000000000000000000000000..52ec53f5295991a6f260f54ef32eccbfc9db64de --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Page.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.executor; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Collections; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Page { + + private long total = 0; + private long current = 1; + private long size = 10; + private List records = Collections.emptyList(); + + public Page(long current, long size) { + this.current = current; + this.size = size; + } + + @Override + public String toString() { + return "LIMIT " + (current - 1) * size + ", " + size; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java new file mode 100644 index 0000000000000000000000000000000000000000..6618c5078c18e4bbaa654ec169e9bc6fa46662f9 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/Result.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.executor; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Collections; +import java.util.List; + +@Data +@NoArgsConstructor +public class Result { + + private E record; + private List records = Collections.emptyList(); + private Page page; + + public Result(E record) { + this.record = record; + } + + public Result(List records) { + this.records = records; + this.record = !records.isEmpty() ? records.get(0) : null; + } + + public Result(Page page) { + this.page = page; + this.records = page.getRecords(); + this.record = !records.isEmpty() ? records.get(0) : null; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/UnionExample.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/UnionExample.java new file mode 100644 index 0000000000000000000000000000000000000000..5ba102e75e8b69ee721bfd7d574be4453a09a00c --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/executor/UnionExample.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.executor; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class UnionExample extends Example { + + private List examples = new ArrayList<>(); + + @Override + public boolean isDirtyQuery() { + return !examples.isEmpty(); + } + + public void addExample(Example example) { + examples.add(example); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Condition.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Condition.java new file mode 100644 index 0000000000000000000000000000000000000000..1736220bd8f97a0234a194e439c2d7e8ec38b702 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Condition.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.operation; + +import com.gitee.dorive.core.entity.executor.Example; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class Condition extends Operation { + + protected Object primaryKey; + protected Example example; + + public Condition(int type, Object entity) { + super(type, entity); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Delete.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Delete.java new file mode 100644 index 0000000000000000000000000000000000000000..844a6bb7027b2a591feaaaeec914ff3184a271b3 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Delete.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.operation; + +public class Delete extends Condition { + + public Delete(int type, Object entity) { + super(type, entity); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Insert.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Insert.java new file mode 100644 index 0000000000000000000000000000000000000000..243cd3ba8df413be0321487cf5a849cf3a50ef88 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Insert.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.operation; + +public class Insert extends Operation { + + public Insert(int type, Object entity) { + super(type, entity); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Operation.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Operation.java new file mode 100644 index 0000000000000000000000000000000000000000..960af73e692664984084f4949cbae216a84af04d --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Operation.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.operation; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Operation { + + public static final int NONE = 0x00000000; + public static final int SELECT = 0x00000001; + public static final int INSERT = 0x00000002; + public static final int UPDATE = 0x00000004; + public static final int DELETE = 0x00000008; + public static final int INSERT_OR_UPDATE = INSERT | UPDATE; + public static final int UPDATE_OR_DELETE = UPDATE | DELETE; + public static final int FORCE_IGNORE = 0x00000010; + public static final int FORCE_INSERT = 0x00000010 | INSERT; + + protected int type; + protected Object entity; + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Query.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Query.java new file mode 100644 index 0000000000000000000000000000000000000000..47d793808e5254cee6c13fe1cc45553978522b15 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Query.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.operation; + +public class Query extends Condition { + + public Query(int type, Object entity) { + super(type, entity); + } + + public boolean withoutPage() { + return example.getPage() == null; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Update.java b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Update.java new file mode 100644 index 0000000000000000000000000000000000000000..cb121bfe80cc3a3a578d4c692fcf55b34923ea7a --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/entity/operation/Update.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.entity.operation; + +public class Update extends Condition { + + public Update(int type, Object entity) { + super(type, entity); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/DefaultEntityFactory.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/DefaultEntityFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..dca8926bd9c5399ec2ab16da85972ffddf996102 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/DefaultEntityFactory.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.api.EntityFactory; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DefaultEntityFactory implements EntityFactory { + + private EntityElement entityElement; + private Class pojoClass; + + @Override + public Object reconstitute(BoundedContext boundedContext, Object persistentObject) { + if (persistentObject instanceof Map) { + return BeanUtil.mapToBean((Map) persistentObject, entityElement.getGenericEntityClass(), true, CopyOptions.create().ignoreNullValue()); + } else { + return BeanUtil.copyProperties(persistentObject, entityElement.getGenericEntityClass()); + } + } + + @Override + public Object deconstruct(BoundedContext boundedContext, Object entity) { + return BeanUtil.copyProperties(entity, pojoClass); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/OperationTypeResolver.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/OperationTypeResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..0544b909e9f4f141423300df278052a83350c254 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/OperationTypeResolver.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl; + +import com.gitee.dorive.core.entity.definition.EntityDefinition; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.Command; +import org.apache.commons.lang3.StringUtils; + +public class OperationTypeResolver { + + public int resolveOperationType(BoundedContext boundedContext, ConfiguredRepository repository) { + EntityDefinition entityDefinition = repository.getEntityDefinition(); + String commandKey = entityDefinition.getCommandKey(); + if (StringUtils.isNotBlank(commandKey) && boundedContext.containsKey(commandKey)) { + Command command = (Command) boundedContext.get(commandKey); + if (command.isForceIgnore()) { + return Operation.FORCE_IGNORE; + + } else if (command.isForceInsert()) { + return Operation.FORCE_INSERT; + } + } + return Operation.NONE; + } + + public int mergeOperationType(int expectedOperationType, int contextOperationType, Object primaryKey) { + if (contextOperationType == Operation.FORCE_IGNORE) { + return Operation.FORCE_IGNORE; + + } else if (contextOperationType == Operation.FORCE_INSERT) { + return expectedOperationType & Operation.INSERT; + + } else if (expectedOperationType == Operation.INSERT_OR_UPDATE) { + return Operation.INSERT_OR_UPDATE; + + } else { + contextOperationType = primaryKey == null ? Operation.INSERT : Operation.UPDATE_OR_DELETE; + return expectedOperationType & contextOperationType; + } + } + +} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityPropertyFactory.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/PropertyProxyFactory.java similarity index 43% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityPropertyFactory.java rename to dorive-core/src/main/java/com/gitee/dorive/core/impl/PropertyProxyFactory.java index f25d3beb007f114b5d15c1740a18b3c40fb0c278..8d791153e66c7f077299cfdad7e0b11e651549eb 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityPropertyFactory.java +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/PropertyProxyFactory.java @@ -1,31 +1,64 @@ -package com.gitee.spring.domain.core.impl; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; -import com.gitee.spring.domain.core.api.EntityProperty; -import com.gitee.spring.domain.core.api.ProxyCompiler; -import com.gitee.spring.domain.core.compile.JavassistCompiler; -import com.gitee.spring.domain.core.utils.ReflectUtils; +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.proxy.ProxyCompiler; +import com.gitee.dorive.proxy.JavassistCompiler; +import com.gitee.dorive.core.util.ReflectUtils; +import java.lang.reflect.Field; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -public class EntityPropertyFactory { +public class PropertyProxyFactory { private static final AtomicInteger COUNT = new AtomicInteger(0); private static final ProxyCompiler PROXY_COMPILER = new JavassistCompiler(); - private static final Map GENERATED_PROXY_CACHE = new ConcurrentHashMap<>(); + private static final Map GENERATED_PROXY_CACHE = new ConcurrentHashMap<>(); - public static EntityProperty newEntityProperty(Class lastEntityClass, Class entityClass, String fieldName) { - String cacheKey = lastEntityClass.getTypeName() + ":" + entityClass.getTypeName() + ":" + fieldName; + public static PropertyProxy newPropertyProxy(Class entityClass, Field declaredField) { + return newPropertyProxy(entityClass, declaredField.getType(), declaredField.getName()); + } + + public static PropertyProxy newPropertyProxy(Class entityClass, String fieldName) { + try { + Field field = ReflectUtil.getField(entityClass, fieldName); + Class fieldClass = field.getType(); + return newPropertyProxy(entityClass, fieldClass, fieldName); + + } catch (Exception e) { + throw new RuntimeException("Failed to generate class!", e); + } + } + + public static PropertyProxy newPropertyProxy(Class entityClass, Class fieldClass, String fieldName) { + String cacheKey = entityClass.getTypeName() + ":" + fieldClass.getTypeName() + ":" + fieldName; if (!GENERATED_PROXY_CACHE.containsKey(cacheKey)) { synchronized (GENERATED_PROXY_CACHE) { if (!GENERATED_PROXY_CACHE.containsKey(cacheKey)) { try { - String generatedCode = generateCode(lastEntityClass, entityClass, fieldName); + String generatedCode = generateCode(entityClass, fieldClass, fieldName); Class generatedClass = PROXY_COMPILER.compile(generatedCode, null); - EntityProperty entityProperty = (EntityProperty) ReflectUtils.newInstance(generatedClass); - GENERATED_PROXY_CACHE.put(cacheKey, entityProperty); + PropertyProxy propertyProxy = (PropertyProxy) ReflectUtils.newInstance(generatedClass); + GENERATED_PROXY_CACHE.put(cacheKey, propertyProxy); } catch (Exception e) { throw new RuntimeException("Failed to generate class!", e); @@ -36,21 +69,21 @@ public class EntityPropertyFactory { return GENERATED_PROXY_CACHE.get(cacheKey); } - private static String generateCode(Class lastEntityClass, Class entityClass, String fieldName) { - Class interfaceClass = EntityProperty.class; + private static String generateCode(Class entityClass, Class fieldClass, String fieldName) { + Class interfaceClass = PropertyProxy.class; StringBuilder builder = new StringBuilder(); String simpleName = interfaceClass.getSimpleName() + "$Proxy" + COUNT.getAndIncrement(); builder.append(String.format("package %s;\n", interfaceClass.getPackage().getName())); builder.append(String.format("public class %s implements %s {\n", simpleName, interfaceClass.getName())); builder.append("\t").append(String.format("public %s getValue(%s arg0) {\n", Object.class.getTypeName(), Object.class.getTypeName())); - builder.append("\t\t").append(String.format("%s arg1 = (%s)arg0;\n", lastEntityClass.getTypeName(), lastEntityClass.getTypeName())); + builder.append("\t\t").append(String.format("%s arg1 = (%s)arg0;\n", entityClass.getTypeName(), entityClass.getTypeName())); builder.append("\t\t").append(String.format("return arg1.get%s();\n", StrUtil.upperFirst(fieldName))); builder.append("\t").append("}\n"); builder.append("\t").append(String.format("public void setValue(%s arg0, %s arg1) {\n", Object.class.getTypeName(), Object.class.getTypeName())); - builder.append("\t\t").append(String.format("%s arg2 = (%s)arg0;\n", lastEntityClass.getTypeName(), lastEntityClass.getTypeName())); - builder.append("\t\t").append(String.format("%s arg3 = (%s)arg1;\n", entityClass.getTypeName(), entityClass.getTypeName())); + builder.append("\t\t").append(String.format("%s arg2 = (%s)arg0;\n", entityClass.getTypeName(), entityClass.getTypeName())); + builder.append("\t\t").append(String.format("%s arg3 = (%s)arg1;\n", fieldClass.getTypeName(), fieldClass.getTypeName())); builder.append("\t\t").append(String.format("arg2.set%s(arg3);\n", StrUtil.upperFirst(fieldName))); builder.append("\t").append("}\n"); diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/AbstractBinder.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/AbstractBinder.java new file mode 100644 index 0000000000000000000000000000000000000000..ba140812e1c7f7ce47d7e7c42f4252678c6ca41d --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/AbstractBinder.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.binder; + +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.api.Binder; +import com.gitee.dorive.core.api.Processor; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.PropertyChain; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public abstract class AbstractBinder implements Binder, Processor { + + protected BindingDefinition bindingDefinition; + protected PropertyChain fieldPropertyChain; + protected Processor processor; + + @Override + public BindingDefinition getBindingDefinition() { + return bindingDefinition; + } + + @Override + public Object getFieldValue(BoundedContext boundedContext, Object entity) { + return fieldPropertyChain.getValue(entity); + } + + @Override + public void setFieldValue(BoundedContext boundedContext, Object entity, Object property) { + fieldPropertyChain.setValue(entity, property); + } + + @Override + public Object input(BoundedContext boundedContext, Object valueObject) { + return processor.input(boundedContext, valueObject); + } + + @Override + public Object output(BoundedContext boundedContext, Object valueObject) { + return processor.output(boundedContext, valueObject); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/ContextBinder.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/ContextBinder.java new file mode 100644 index 0000000000000000000000000000000000000000..125d2afb6b05353d30e583897edaa543ec238882 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/ContextBinder.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.binder; + +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.api.Processor; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.PropertyChain; + +public class ContextBinder extends AbstractBinder { + + public ContextBinder(BindingDefinition bindingDefinition, + PropertyChain fieldPropertyChain, + Processor processor) { + super(bindingDefinition, fieldPropertyChain, processor); + } + + @Override + public Object getBoundValue(BoundedContext boundedContext, Object rootEntity) { + String bindCtx = bindingDefinition.getBindCtx(); + return boundedContext.get(bindCtx); + } + + @Override + public void setBoundValue(BoundedContext boundedContext, Object rootEntity, Object property) { + // ignore + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/PropertyBinder.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/PropertyBinder.java new file mode 100644 index 0000000000000000000000000000000000000000..6e7c06bbe8ab9218ff119297390d89c9244d57ed --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/binder/PropertyBinder.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.binder; + +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.api.Processor; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.PropertyChain; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PropertyBinder extends AbstractBinder { + + protected String belongAccessPath; + protected ConfiguredRepository belongRepository; + protected PropertyChain boundPropertyChain; + + public PropertyBinder(BindingDefinition bindingDefinition, + PropertyChain fieldPropertyChain, + Processor processor, + String belongAccessPath, + ConfiguredRepository belongRepository, + PropertyChain boundPropertyChain) { + super(bindingDefinition, fieldPropertyChain, processor); + this.belongAccessPath = belongAccessPath; + this.belongRepository = belongRepository; + this.boundPropertyChain = boundPropertyChain; + } + + public boolean isSameType() { + return fieldPropertyChain.getProperty().isSameType(boundPropertyChain.getProperty()); + } + + @Override + public Object getBoundValue(BoundedContext boundedContext, Object rootEntity) { + return boundPropertyChain.getValue(rootEntity); + } + + @Override + public void setBoundValue(BoundedContext boundedContext, Object rootEntity, Object property) { + boundPropertyChain.setValue(rootEntity, property); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/executor/AbstractExecutor.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/executor/AbstractExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..d55aaf85572c96590046a76ca050ecf9c12aa61d --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/executor/AbstractExecutor.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.executor; + +import com.gitee.dorive.core.entity.operation.Delete; +import com.gitee.dorive.core.entity.operation.Insert; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.entity.operation.Query; +import com.gitee.dorive.core.entity.operation.Update; +import com.gitee.dorive.core.api.Executor; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.executor.Example; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public abstract class AbstractExecutor implements Executor { + + protected EntityElement entityElement; + + @Override + public Query buildQueryByPK(BoundedContext boundedContext, Object primaryKey) { + Query query = new Query(Operation.SELECT, null); + query.setPrimaryKey(primaryKey); + return query; + } + + @Override + public Query buildQuery(BoundedContext boundedContext, Example example) { + Query query = new Query(Operation.SELECT, null); + query.setExample(example); + return query; + } + + @Override + public Insert buildInsert(BoundedContext boundedContext, Object entity) { + return new Insert(Operation.INSERT, entity); + } + + @Override + public Update buildUpdate(BoundedContext boundedContext, Object entity) { + Update update = new Update(Operation.UPDATE, entity); + Object primaryKey = entityElement.getPrimaryKeyProxy().getValue(entity); + update.setPrimaryKey(primaryKey); + return update; + } + + @Override + public Update buildUpdate(BoundedContext boundedContext, Object entity, Example example) { + Update update = new Update(Operation.UPDATE, entity); + update.setExample(example); + return update; + } + + @Override + public Operation buildInsertOrUpdate(BoundedContext boundedContext, Object entity) { + Object primaryKey = entityElement.getPrimaryKeyProxy().getValue(entity); + if (primaryKey == null) { + return new Insert(Operation.INSERT, entity); + } else { + Update update = new Update(Operation.UPDATE, entity); + update.setPrimaryKey(primaryKey); + return update; + } + } + + @Override + public Delete buildDelete(BoundedContext boundedContext, Object entity) { + Delete delete = new Delete(Operation.DELETE, entity); + Object primaryKey = entityElement.getPrimaryKeyProxy().getValue(entity); + delete.setPrimaryKey(primaryKey); + return delete; + } + + @Override + public Delete buildDeleteByPK(BoundedContext boundedContext, Object primaryKey) { + Delete delete = new Delete(Operation.DELETE, null); + delete.setPrimaryKey(primaryKey); + return delete; + } + + @Override + public Delete buildDelete(BoundedContext boundedContext, Example example) { + Delete delete = new Delete(Operation.DELETE, null); + delete.setExample(example); + return delete; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/executor/ChainExecutor.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/executor/ChainExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..ec471fc0cfdfe84917f0d0ea57d7f5fd8a6b473e --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/executor/ChainExecutor.java @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.executor; + +import cn.hutool.core.lang.Assert; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.entity.operation.Query; +import com.gitee.dorive.core.api.Binder; +import com.gitee.dorive.core.api.EntityHandler; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.PropertyChain; +import com.gitee.dorive.core.impl.OperationTypeResolver; +import com.gitee.dorive.core.impl.resolver.DelegateResolver; +import com.gitee.dorive.core.repository.AbstractContextRepository; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Getter +@Setter +@ToString +public class ChainExecutor extends AbstractExecutor implements EntityHandler { + + private final AbstractContextRepository repository; + private final EntityHandler entityHandler; + + private final OperationTypeResolver operationTypeResolver = new OperationTypeResolver(); + + public ChainExecutor(AbstractContextRepository repository, EntityHandler entityHandler) { + super(repository.getEntityElement()); + this.repository = repository; + this.entityHandler = entityHandler; + } + + @Override + public Result executeQuery(BoundedContext boundedContext, Query query) { + ConfiguredRepository rootRepository = repository.getRootRepository(); + if (query.getPrimaryKey() != null) { + Object rootEntity = rootRepository.selectByPrimaryKey(boundedContext, query.getPrimaryKey()); + if (rootEntity != null) { + handleEntities(boundedContext, Collections.singletonList(rootEntity)); + } + return new Result<>(rootEntity); + + } else if (query.getExample() != null) { + Result result = rootRepository.selectResultByExample(boundedContext, query.getExample()); + List rootEntities = result.getRecords(); + if (!rootEntities.isEmpty()) { + handleEntities(boundedContext, rootEntities); + } + return result; + + } else { + throw new RuntimeException("Unsupported query method!"); + } + } + + @Override + public void handleEntities(BoundedContext boundedContext, List rootEntities) { + entityHandler.handleEntities(boundedContext, rootEntities); + } + + @Override + public Operation buildInsertOrUpdate(BoundedContext boundedContext, Object entity) { + return new Operation(Operation.INSERT_OR_UPDATE, entity); + } + + @Override + public int execute(BoundedContext boundedContext, Operation operation) { + int expectedOperationType = operation.getType(); + boolean isInsertContext = (expectedOperationType & Operation.INSERT) == Operation.INSERT; + + Object rootEntity = operation.getEntity(); + Assert.notNull(rootEntity, "The rootEntity cannot be null!"); + + DelegateResolver delegateResolver = repository.getDelegateResolver(); + AbstractContextRepository delegateRepository = delegateResolver.delegateRepository(rootEntity); + delegateRepository = delegateRepository == null ? repository : delegateRepository; + + int totalCount = 0; + for (ConfiguredRepository repository : delegateRepository.getOrderedRepositories()) { + PropertyChain anchorPoint = repository.getAnchorPoint(); + Object targetEntity = anchorPoint == null ? rootEntity : anchorPoint.getValue(rootEntity); + + if (targetEntity != null && repository.matchKeys(boundedContext)) { + int contextOperationType = operationTypeResolver.resolveOperationType(boundedContext, repository); + + Collection collection; + Object boundIdEntity = null; + if (targetEntity instanceof Collection) { + collection = (Collection) targetEntity; + } else { + collection = Collections.singletonList(targetEntity); + boundIdEntity = targetEntity; + } + + for (Object entity : collection) { + Object primaryKey = repository.getPrimaryKey(entity); + int operationType = operationTypeResolver.mergeOperationType(expectedOperationType, contextOperationType, primaryKey); + if ((operationType & Operation.INSERT) == Operation.INSERT) { + getBoundValueFromContext(boundedContext, rootEntity, repository, entity); + } + operationType = repository.isAggregated() ? expectedOperationType : operationType; + totalCount += doExecute(boundedContext, repository, entity, operationType); + } + + if (isInsertContext && boundIdEntity != null) { + setBoundIdForBoundEntity(boundedContext, rootEntity, repository, boundIdEntity); + } + } + } + return totalCount; + } + + private int doExecute(BoundedContext boundedContext, ConfiguredRepository repository, Object entity, int operationType) { + if (operationType == Operation.INSERT) { + return repository.insert(boundedContext, entity); + + } else if (operationType == Operation.UPDATE) { + return repository.update(boundedContext, entity); + + } else if (operationType == Operation.INSERT_OR_UPDATE) { + return repository.insertOrUpdate(boundedContext, entity); + + } else if (operationType == Operation.DELETE) { + return repository.delete(boundedContext, entity); + } + return 0; + } + + private void getBoundValueFromContext(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository repository, Object entity) { + for (Binder binder : repository.getBinderResolver().getBoundValueBinders()) { + Object fieldValue = binder.getFieldValue(boundedContext, entity); + if (fieldValue == null) { + Object boundValue = binder.getBoundValue(boundedContext, rootEntity); + if (boundValue != null) { + binder.setFieldValue(boundedContext, entity, boundValue); + } + } + } + } + + private void setBoundIdForBoundEntity(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository repository, Object entity) { + Binder binder = repository.getBinderResolver().getBoundIdBinder(); + if (binder != null) { + Object boundValue = binder.getBoundValue(boundedContext, rootEntity); + if (boundValue == null) { + Object primaryKey = binder.getFieldValue(boundedContext, entity); + if (primaryKey != null) { + binder.setBoundValue(boundedContext, rootEntity, primaryKey); + } + } + } + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/handler/AdaptiveEntityHandler.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/handler/AdaptiveEntityHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..2784fe53d0231f941af87fbcc9355ce442cf2044 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/handler/AdaptiveEntityHandler.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.handler; + +import com.gitee.dorive.core.api.EntityHandler; +import com.gitee.dorive.core.api.Executor; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.impl.resolver.DelegateResolver; +import com.gitee.dorive.core.repository.AbstractContextRepository; +import lombok.Data; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Data +public class AdaptiveEntityHandler implements EntityHandler { + + private final AbstractContextRepository repository; + private final EntityHandler entityHandler; + + public AdaptiveEntityHandler(AbstractContextRepository repository, EntityHandler entityHandler) { + this.repository = repository; + this.entityHandler = entityHandler; + } + + @Override + public void handleEntities(BoundedContext boundedContext, List rootEntities) { + List newRootEntities = new ArrayList<>(rootEntities.size()); + int delegateCount = repository.getDelegateResolver().getDelegateCount(); + Map, List> repositoryEntitiesMap = new LinkedHashMap<>(delegateCount * 4 / 3 + 1); + filterRootEntities(rootEntities, newRootEntities, repositoryEntitiesMap); + if (!newRootEntities.isEmpty()) { + entityHandler.handleEntities(boundedContext, newRootEntities); + } + repositoryEntitiesMap.forEach((repository, entities) -> { + Executor executor = repository.getExecutor(); + if (executor instanceof EntityHandler) { + ((EntityHandler) executor).handleEntities(boundedContext, entities); + } + }); + } + + private void filterRootEntities(List rootEntities, List newRootEntities, + Map, List> repositoryEntitiesMap) { + DelegateResolver delegateResolver = repository.getDelegateResolver(); + for (Object rootEntity : rootEntities) { + AbstractContextRepository repository = delegateResolver.delegateRepository(rootEntity); + if (repository == null) { + newRootEntities.add(rootEntity); + } else { + List existRootEntities = repositoryEntitiesMap.computeIfAbsent(repository, key -> new ArrayList<>(rootEntities.size())); + existRootEntities.add(rootEntity); + } + } + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/handler/BatchEntityHandler.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/handler/BatchEntityHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..480dce5ebbba3b3d54b5212172d9e77ff40466a6 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/handler/BatchEntityHandler.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.handler; + +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.executor.UnionExample; +import com.gitee.dorive.core.api.EntityHandler; +import com.gitee.dorive.core.api.EntityIndex; +import com.gitee.dorive.core.api.ExampleBuilder; +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.PropertyChain; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.repository.AbstractContextRepository; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +public class BatchEntityHandler implements EntityHandler { + + private final AbstractContextRepository repository; + + public BatchEntityHandler(AbstractContextRepository repository) { + this.repository = repository; + } + + @Override + public void handleEntities(BoundedContext boundedContext, List rootEntities) { + for (ConfiguredRepository repository : this.repository.getSubRepositories()) { + if (repository.matchKeys(boundedContext)) { + UnionExample unionExample = newUnionExample(repository, boundedContext, rootEntities); + if (!unionExample.isDirtyQuery()) { + continue; + } + Result result = repository.selectResultByExample(boundedContext, unionExample); + if (!(result instanceof EntityIndex)) { + continue; + } + setValueForRootEntities(repository, rootEntities, (EntityIndex) result); + } + } + } + + private UnionExample newUnionExample(ConfiguredRepository repository, BoundedContext boundedContext, List rootEntities) { + ConfiguredRepository rootRepository = this.repository.getRootRepository(); + + PropertyChain anchorPoint = repository.getAnchorPoint(); + PropertyChain lastPropertyChain = anchorPoint.getLastPropertyChain(); + + String builderKey = repository.getEntityDefinition().getBuilderKey(); + ExampleBuilder exampleBuilder = StringUtils.isNotBlank(builderKey) ? (ExampleBuilder) boundedContext.get(builderKey) : null; + + UnionExample unionExample = new UnionExample(); + for (Object rootEntity : rootEntities) { + Object lastEntity = lastPropertyChain == null ? rootEntity : lastPropertyChain.getValue(rootEntity); + if (lastEntity != null) { + Example example = repository.newExampleByContext(boundedContext, rootEntity); + if (exampleBuilder != null) { + example = exampleBuilder.buildExample(boundedContext, rootEntity, example); + } + if (example.isDirtyQuery()) { + Object primaryKey = rootRepository.getPrimaryKey(rootEntity); + example.selectColumns(primaryKey + " as $id"); + unionExample.addExample(example); + } + } + } + return unionExample; + } + + private void setValueForRootEntities(ConfiguredRepository repository, List rootEntities, EntityIndex entityIndex) { + ConfiguredRepository rootRepository = this.repository.getRootRepository(); + + PropertyChain anchorPoint = repository.getAnchorPoint(); + PropertyChain lastPropertyChain = anchorPoint.getLastPropertyChain(); + PropertyProxy propertyProxy = anchorPoint.getPropertyProxy(); + + for (Object rootEntity : rootEntities) { + Object lastEntity = lastPropertyChain == null ? rootEntity : lastPropertyChain.getValue(rootEntity); + if (lastEntity != null) { + Object primaryKey = rootRepository.getPrimaryKey(rootEntity); + List entities = entityIndex.selectList(rootEntity, primaryKey); + Object entity = repository.convertManyToOne(entities); + if (entity != null) { + propertyProxy.setValue(lastEntity, entity); + } + } + } + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/processor/DefaultProcessor.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/processor/DefaultProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..2fd3d9627f4b3207949e2dfc497cb2fb13e17934 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/processor/DefaultProcessor.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.processor; + +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.api.Processor; +import com.gitee.dorive.core.entity.BoundedContext; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class DefaultProcessor implements Processor { + + protected BindingDefinition bindingDefinition; + + @Override + public Object input(BoundedContext boundedContext, Object valueObject) { + return valueObject; + } + + @Override + public Object output(BoundedContext boundedContext, Object valueObject) { + return valueObject; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/processor/PropertyProcessor.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/processor/PropertyProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..f6493a3ae8d78a1dff8ffe3c89cb0b34b18e18e0 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/processor/PropertyProcessor.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.gitee.dorive.core.impl.processor; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.gitee.dorive.core.entity.BoundedContext; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Collection; + +@Data +@EqualsAndHashCode(callSuper = false) +public class PropertyProcessor extends DefaultProcessor { + + @Override + public Object input(BoundedContext boundedContext, Object valueObject) { + String property = bindingDefinition.getProperty(); + if (valueObject instanceof Collection) { + return CollUtil.map((Collection) valueObject, item -> BeanUtil.getFieldValue(item, property), true); + } else { + return BeanUtil.getFieldValue(valueObject, property); + } + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/BinderResolver.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/BinderResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..6e90b7384199991425e0a9d9e8eda1f6bc31b8c2 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/BinderResolver.java @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.resolver; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.entity.definition.EntityDefinition; +import com.gitee.dorive.core.impl.binder.ContextBinder; +import com.gitee.dorive.core.impl.binder.PropertyBinder; +import com.gitee.dorive.core.impl.processor.DefaultProcessor; +import com.gitee.dorive.core.impl.processor.PropertyProcessor; +import com.gitee.dorive.core.api.Binder; +import com.gitee.dorive.core.api.Processor; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.PropertyChain; +import com.gitee.dorive.core.repository.AbstractContextRepository; +import com.gitee.dorive.core.repository.ConfiguredRepository; +import com.gitee.dorive.core.util.PathUtils; +import com.gitee.dorive.core.util.ReflectUtils; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.ApplicationContext; + +import java.util.*; + +@Data +public class BinderResolver { + + private AbstractContextRepository repository; + + private List allBinders; + private List propertyBinders; + private String[] boundColumns; + private List contextBinders; + private List boundValueBinders; + private PropertyBinder boundIdBinder; + + public BinderResolver(AbstractContextRepository repository) { + this.repository = repository; + } + + public void resolveAllBinders(String accessPath, EntityElement entityElement, EntityDefinition entityDefinition, + String fieldPrefix, PropertyResolver propertyResolver) { + + List bindingDefinitions = BindingDefinition.newBindingDefinitions(entityElement); + Map allPropertyChainMap = propertyResolver.getAllPropertyChainMap(); + + allBinders = new ArrayList<>(bindingDefinitions.size()); + propertyBinders = new ArrayList<>(bindingDefinitions.size()); + Set boundColumns = new LinkedHashSet<>(bindingDefinitions.size() * 4 / 3 + 1); + contextBinders = new ArrayList<>(bindingDefinitions.size()); + boundValueBinders = new ArrayList<>(bindingDefinitions.size()); + boundIdBinder = null; + + for (BindingDefinition bindingDefinition : bindingDefinitions) { + renewBindingDefinition(accessPath, bindingDefinition); + + String field = bindingDefinition.getField(); + PropertyChain fieldPropertyChain = allPropertyChainMap.get(fieldPrefix + field); + Assert.notNull(fieldPropertyChain, "The field property chain cannot be null! entity: {}, field: {}", + entityElement.getGenericEntityClass().getSimpleName(), field); + fieldPropertyChain.initialize(); + + Processor processor = newProcessor(bindingDefinition); + + if (StringUtils.isNotBlank(bindingDefinition.getBindProp())) { + PropertyBinder propertyBinder = newPropertyBinder(bindingDefinition, fieldPropertyChain, processor); + allBinders.add(propertyBinder); + propertyBinders.add(propertyBinder); + boundColumns.add(StrUtil.toUnderlineCase(bindingDefinition.getAlias())); + + if (propertyBinder.isSameType()) { + if (!"id".equals(field)) { + boundValueBinders.add(propertyBinder); + } else { + if (entityDefinition.getOrder() == 0) { + entityDefinition.setOrder(-1); + } + boundIdBinder = propertyBinder; + } + } + + } else { + ContextBinder contextBinder = new ContextBinder(bindingDefinition, fieldPropertyChain, processor); + allBinders.add(contextBinder); + contextBinders.add(contextBinder); + boundValueBinders.add(contextBinder); + } + } + + this.boundColumns = boundColumns.toArray(new String[0]); + } + + private void renewBindingDefinition(String accessPath, BindingDefinition bindingDefinition) { + String field = bindingDefinition.getField(); + String bindProp = bindingDefinition.getBindProp(); + String property = bindingDefinition.getProperty(); + Class processor = bindingDefinition.getProcessor(); + String bindCtx = bindingDefinition.getBindCtx(); + String alias = bindingDefinition.getAlias(); + String bindAlias = bindingDefinition.getBindAlias(); + + Assert.notBlank(bindProp + bindCtx, "The bindProp and bindCtx cannot be blank at the same time!"); + + if (StringUtils.isBlank(alias)) { + alias = field; + } + if (StringUtils.isBlank(bindAlias)) { + bindAlias = property; + } + + if (StringUtils.isNotBlank(bindProp)) { + Assert.isTrue(bindProp.startsWith("/") || bindProp.startsWith("."), "The bindProp must be a path!"); + if (bindProp.startsWith(".")) { + bindProp = PathUtils.getAbsolutePath(accessPath, bindProp); + } + if (StringUtils.isBlank(bindAlias)) { + bindAlias = PathUtils.getFieldName(bindProp); + } + } + + bindingDefinition.setField(field); + bindingDefinition.setBindProp(bindProp); + bindingDefinition.setProperty(property); + bindingDefinition.setProcessor(processor); + bindingDefinition.setBindCtx(bindCtx); + bindingDefinition.setAlias(alias); + bindingDefinition.setBindAlias(bindAlias); + } + + private Processor newProcessor(BindingDefinition bindingDefinition) { + Class processorClass = bindingDefinition.getProcessor(); + Processor processor = null; + if (processorClass == DefaultProcessor.class) { + if (StringUtils.isBlank(bindingDefinition.getProperty())) { + processor = new DefaultProcessor(); + } else { + processor = new PropertyProcessor(); + } + } else { + ApplicationContext applicationContext = repository.getApplicationContext(); + String[] beanNamesForType = applicationContext.getBeanNamesForType(processorClass); + if (beanNamesForType.length > 0) { + processor = (Processor) applicationContext.getBean(beanNamesForType[0]); + } + if (processor == null) { + processor = (Processor) ReflectUtils.newInstance(processorClass); + } + } + if (processor instanceof DefaultProcessor) { + DefaultProcessor defaultProcessor = (DefaultProcessor) processor; + defaultProcessor.setBindingDefinition(bindingDefinition); + } + if (processor instanceof PropertyProcessor) { + Assert.notBlank(bindingDefinition.getProperty(), "The property of PropertyProcessor cannot be blank!"); + } + return processor; + } + + private PropertyBinder newPropertyBinder(BindingDefinition bindingDefinition, PropertyChain fieldPropertyChain, Processor processor) { + Map allRepositoryMap = repository.getAllRepositoryMap(); + String belongAccessPath = PathUtils.getBelongPath(allRepositoryMap.keySet(), bindingDefinition.getBindProp()); + ConfiguredRepository belongRepository = allRepositoryMap.get(belongAccessPath); + Assert.notNull(belongRepository, "The belong repository cannot be null!"); + belongRepository.setBoundEntity(true); + + Map allPropertyChainMap = repository.getPropertyResolver().getAllPropertyChainMap(); + PropertyChain boundPropertyChain = allPropertyChainMap.get(bindingDefinition.getBindProp()); + Assert.notNull(boundPropertyChain, "The bound property chain cannot be null!"); + boundPropertyChain.initialize(); + + return new PropertyBinder(bindingDefinition, fieldPropertyChain, processor, belongAccessPath, belongRepository, boundPropertyChain); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/DelegateResolver.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/DelegateResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..831d2cea5ebe6d5599db9d0ee7e574e0781fd4ee --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/DelegateResolver.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.resolver; + +import com.gitee.dorive.core.repository.AbstractContextRepository; +import lombok.Data; +import org.springframework.context.ApplicationContext; +import org.springframework.util.ReflectionUtils; + +import java.util.LinkedHashMap; +import java.util.Map; + +@Data +public class DelegateResolver { + + private AbstractContextRepository repository; + + private Map, AbstractContextRepository> delegateRepositoryMap = new LinkedHashMap<>(3 * 4 / 3 + 1); + + public DelegateResolver(AbstractContextRepository repository) { + this.repository = repository; + } + + public void resolveDelegateRepositoryMap() { + ReflectionUtils.doWithLocalFields(repository.getClass(), declaredField -> { + Class fieldClass = declaredField.getType(); + if (AbstractContextRepository.class.isAssignableFrom(fieldClass)) { + ApplicationContext applicationContext = repository.getApplicationContext(); + Object beanInstance = applicationContext.getBean(fieldClass); + AbstractContextRepository abstractContextRepository = (AbstractContextRepository) beanInstance; + Class fieldEntityClass = abstractContextRepository.getEntityClass(); + if (repository.getEntityClass().isAssignableFrom(fieldEntityClass)) { + delegateRepositoryMap.put(fieldEntityClass, abstractContextRepository); + } + } + }); + } + + public boolean isDelegated() { + return !delegateRepositoryMap.isEmpty(); + } + + public int getDelegateCount() { + return delegateRepositoryMap.size(); + } + + public AbstractContextRepository delegateRepository(Object rootEntity) { + return delegateRepositoryMap.get(rootEntity.getClass()); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/PropertyResolver.java b/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/PropertyResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..bf8b9e0ae11c66c32c7fde33340709ed995c7954 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/impl/resolver/PropertyResolver.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.impl.resolver; + +import com.gitee.dorive.core.annotation.Entity; +import com.gitee.dorive.core.entity.Property; +import com.gitee.dorive.core.entity.PropertyChain; +import lombok.Data; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.util.ReflectionUtils; + +import java.util.LinkedHashMap; +import java.util.Map; + +@Data +public class PropertyResolver { + + private boolean ignoreAnnotated; + private Map allPropertyChainMap = new LinkedHashMap<>(); + + public PropertyResolver(boolean ignoreAnnotated) { + this.ignoreAnnotated = ignoreAnnotated; + } + + public void resolveProperties(Class entityClass) { + resolveProperties("", entityClass); + } + + public void resolveProperties(String lastAccessPath, Class entityClass) { + PropertyChain lastPropertyChain = allPropertyChainMap.get(lastAccessPath); + ReflectionUtils.doWithLocalFields(entityClass, declaredField -> { + String accessPath = lastAccessPath + "/" + declaredField.getName(); + boolean isAnnotatedEntity = AnnotatedElementUtils.isAnnotated(declaredField, Entity.class); + Property property = new Property(declaredField); + + PropertyChain propertyChain = new PropertyChain( + lastPropertyChain, + entityClass, + accessPath, + isAnnotatedEntity, + property, + null); + + if (isAnnotatedEntity) { + propertyChain.initialize(); + } + + allPropertyChainMap.put(accessPath, propertyChain); + + if (ignoreAnnotated && isAnnotatedEntity) { + return; + } + + Class fieldClass = property.getFieldClass(); + if (!filterEntityClass(fieldClass)) { + resolveProperties(accessPath, fieldClass); + } + }); + } + + private boolean filterEntityClass(Class entityClass) { + String className = entityClass.getName(); + return className.startsWith("java.lang.") || className.startsWith("java.util.") || entityClass.isEnum(); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractContextRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractContextRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..66c331069211dc8718771ddaac05f605e28ec246 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractContextRepository.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.repository; + +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.PropertyChain; +import com.gitee.dorive.core.entity.definition.EntityDefinition; +import com.gitee.dorive.core.entity.executor.OrderBy; +import com.gitee.dorive.core.impl.executor.ChainExecutor; +import com.gitee.dorive.core.impl.handler.AdaptiveEntityHandler; +import com.gitee.dorive.core.impl.handler.BatchEntityHandler; +import com.gitee.dorive.core.impl.resolver.BinderResolver; +import com.gitee.dorive.core.impl.resolver.DelegateResolver; +import com.gitee.dorive.core.impl.resolver.PropertyResolver; +import com.gitee.dorive.core.api.EntityHandler; +import com.gitee.dorive.core.api.Executor; +import com.gitee.dorive.core.util.ReflectUtils; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +import java.lang.reflect.AnnotatedElement; +import java.util.*; + +@Data +@EqualsAndHashCode(callSuper = false) +public abstract class AbstractContextRepository extends AbstractRepository implements ApplicationContextAware, InitializingBean { + + protected ApplicationContext applicationContext; + + protected Class entityClass; + + protected DelegateResolver delegateResolver = new DelegateResolver(this); + protected PropertyResolver propertyResolver = new PropertyResolver(false); + + protected Map allRepositoryMap = new LinkedHashMap<>(); + protected ConfiguredRepository rootRepository; + protected List subRepositories = new ArrayList<>(); + protected List orderedRepositories = new ArrayList<>(); + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void afterPropertiesSet() throws Exception { + entityClass = ReflectUtils.getFirstArgumentType(this.getClass()); + delegateResolver.resolveDelegateRepositoryMap(); + + List> allClasses = ReflectUtils.getAllSuperclasses(entityClass, Object.class); + allClasses.add(entityClass); + allClasses.forEach(clazz -> propertyResolver.resolveProperties(clazz)); + + ConfiguredRepository rootRepository = newRepository("/", entityClass); + allRepositoryMap.put("/", rootRepository); + this.rootRepository = rootRepository; + orderedRepositories.add(rootRepository); + + Map allPropertyChainMap = propertyResolver.getAllPropertyChainMap(); + allPropertyChainMap.forEach((accessPath, propertyChain) -> { + if (propertyChain.isAnnotatedEntity()) { + ConfiguredRepository subRepository = newRepository(accessPath, propertyChain.getProperty().getDeclaredField()); + allRepositoryMap.put(accessPath, subRepository); + subRepositories.add(subRepository); + orderedRepositories.add(subRepository); + } + }); + + orderedRepositories.sort(Comparator.comparingInt(repository -> repository.getEntityDefinition().getOrder())); + + setEntityElement(rootRepository.getEntityElement()); + setEntityDefinition(rootRepository.getEntityDefinition()); + + EntityHandler entityHandler = new BatchEntityHandler(this); + if (delegateResolver.isDelegated()) { + entityHandler = new AdaptiveEntityHandler(this, entityHandler); + } + setExecutor(new ChainExecutor(this, entityHandler)); + } + + @SuppressWarnings("unchecked") + private ConfiguredRepository newRepository(String accessPath, AnnotatedElement annotatedElement) { + EntityElement entityElement = EntityElement.newEntityElement(annotatedElement); + EntityDefinition entityDefinition = EntityDefinition.newEntityDefinition(entityElement); + + Class repositoryClass = entityDefinition.getRepository(); + Object repository; + if (repositoryClass == DefaultRepository.class) { + repository = new DefaultRepository(); + } else { + repository = applicationContext.getBean(repositoryClass); + } + if (repository instanceof DefaultRepository) { + DefaultRepository defaultRepository = (DefaultRepository) repository; + defaultRepository.setEntityElement(entityElement); + defaultRepository.setEntityDefinition(entityDefinition); + defaultRepository.setExecutor(newExecutor(entityElement, entityDefinition)); + } + + boolean aggregateRoot = "/".equals(accessPath); + boolean aggregated = !(repository instanceof DefaultRepository); + repository = postProcessRepository((AbstractRepository) repository); + + Map allPropertyChainMap = propertyResolver.getAllPropertyChainMap(); + PropertyChain anchorPoint = allPropertyChainMap.get(accessPath); + + PropertyResolver propertyResolver = new PropertyResolver(true); + String lastAccessPath = aggregateRoot || entityElement.isCollection() ? "" : accessPath; + propertyResolver.resolveProperties(lastAccessPath, entityElement.getGenericEntityClass()); + + OrderBy defaultOrderBy = entityDefinition.getDefaultOrderBy(); + + BinderResolver binderResolver = new BinderResolver(this); + String fieldPrefix = lastAccessPath + "/"; + binderResolver.resolveAllBinders(accessPath, entityElement, entityDefinition, fieldPrefix, propertyResolver); + + ConfiguredRepository configuredRepository = new ConfiguredRepository(); + configuredRepository.setEntityElement(entityElement); + configuredRepository.setEntityDefinition(entityDefinition); + configuredRepository.setProxyRepository((AbstractRepository) repository); + configuredRepository.setAccessPath(accessPath); + configuredRepository.setAggregateRoot(aggregateRoot); + configuredRepository.setAggregated(aggregated); + configuredRepository.setAnchorPoint(anchorPoint); + configuredRepository.setPropertyResolver(propertyResolver); + configuredRepository.setDefaultOrderBy(defaultOrderBy); + configuredRepository.setFieldPrefix(fieldPrefix); + configuredRepository.setBinderResolver(binderResolver); + configuredRepository.setBoundEntity(false); + return configuredRepository; + } + + protected abstract Executor newExecutor(EntityElement entityElement, EntityDefinition entityDefinition); + + protected abstract AbstractRepository postProcessRepository(AbstractRepository repository); + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractGenericRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractGenericRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..2fe08b853dabe15ddbce3594e292146671d2d064 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractGenericRepository.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.repository; + +import cn.hutool.core.lang.Assert; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.api.ListableRepository; +import com.gitee.dorive.core.api.MetadataHolder; +import com.gitee.dorive.core.entity.BoundedContext; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = false) +public abstract class AbstractGenericRepository extends AbstractContextRepository + implements ListableRepository, MetadataHolder { + + @Override + public int updateByExample(BoundedContext boundedContext, Object entity, Example example) { + Assert.notNull(entity, "The entity cannot be null!"); + Assert.notNull(example, "The example cannot be null!"); + int totalCount = 0; + for (ConfiguredRepository repository : getOrderedRepositories()) { + if (repository.matchKeys(boundedContext)) { + totalCount += repository.updateByExample(boundedContext, entity, example); + } + } + return totalCount; + } + + @Override + public int deleteByPrimaryKey(BoundedContext boundedContext, PK primaryKey) { + Assert.notNull(primaryKey, "The primaryKey cannot be null!"); + E entity = selectByPrimaryKey(boundedContext, primaryKey); + return delete(boundedContext, entity); + } + + @Override + public int deleteByExample(BoundedContext boundedContext, Example example) { + Assert.notNull(example, "The example cannot be null!"); + int totalCount = 0; + for (ConfiguredRepository repository : getOrderedRepositories()) { + if (repository.matchKeys(boundedContext)) { + totalCount += repository.deleteByExample(boundedContext, example); + } + } + return totalCount; + } + + @Override + public int insertList(BoundedContext boundedContext, List entities) { + return entities.stream().mapToInt(entity -> insert(boundedContext, entity)).sum(); + } + + @Override + public int updateList(BoundedContext boundedContext, List entities) { + return entities.stream().mapToInt(entity -> update(boundedContext, entity)).sum(); + } + + @Override + public int insertOrUpdateList(BoundedContext boundedContext, List entities) { + return entities.stream().mapToInt(entity -> insertOrUpdate(boundedContext, entity)).sum(); + } + + @Override + public int deleteList(BoundedContext boundedContext, List entities) { + return entities.stream().mapToInt(entity -> delete(boundedContext, entity)).sum(); + } + + @Override + public Object getMetadata() { + return rootRepository.getMetadata(); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..13fa62929a4fd4dc2ecce138ad959b24d536b142 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/repository/AbstractRepository.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.repository; + +import cn.hutool.core.lang.Assert; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.definition.EntityDefinition; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.operation.Delete; +import com.gitee.dorive.core.entity.operation.Insert; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.entity.operation.Query; +import com.gitee.dorive.core.entity.operation.Update; +import com.gitee.dorive.core.api.Executor; +import com.gitee.dorive.core.api.Repository; +import lombok.Data; + +import java.util.List; + +@Data +public abstract class AbstractRepository implements Repository { + + protected EntityElement entityElement; + protected EntityDefinition entityDefinition; + protected Executor executor; + + @Override + @SuppressWarnings("unchecked") + public E selectByPrimaryKey(BoundedContext boundedContext, PK primaryKey) { + Assert.notNull(primaryKey, "The primaryKey cannot be null!"); + Query query = executor.buildQueryByPK(boundedContext, primaryKey); + Result result = executor.executeQuery(boundedContext, query); + return (E) result.getRecord(); + } + + @Override + @SuppressWarnings("unchecked") + public List selectByExample(BoundedContext boundedContext, Example example) { + Assert.notNull(example, "The example cannot be null!"); + Query query = executor.buildQuery(boundedContext, example); + Result result = executor.executeQuery(boundedContext, query); + return (List) result.getRecords(); + } + + @Override + @SuppressWarnings("unchecked") + public Page selectPageByExample(BoundedContext boundedContext, Example example) { + Assert.notNull(example, "The example cannot be null!"); + Assert.notNull(example.getPage(), "The page cannot be null!"); + Query query = executor.buildQuery(boundedContext, example); + Result result = executor.executeQuery(boundedContext, query); + return (Page) result.getPage(); + } + + @Override + @SuppressWarnings("unchecked") + public Result selectResultByExample(BoundedContext boundedContext, Example example) { + Assert.notNull(example, "The example cannot be null!"); + Query query = executor.buildQuery(boundedContext, example); + return (Result) executor.executeQuery(boundedContext, query); + } + + @Override + public int insert(BoundedContext boundedContext, E entity) { + Assert.notNull(entity, "The entity cannot be null!"); + Insert insert = executor.buildInsert(boundedContext, entity); + return executor.execute(boundedContext, insert); + } + + @Override + public int update(BoundedContext boundedContext, E entity) { + Assert.notNull(entity, "The entity cannot be null!"); + Update update = executor.buildUpdate(boundedContext, entity); + return executor.execute(boundedContext, update); + } + + @Override + public int updateByExample(BoundedContext boundedContext, Object entity, Example example) { + Assert.notNull(entity, "The entity cannot be null!"); + Assert.notNull(example, "The example cannot be null!"); + Update update = executor.buildUpdate(boundedContext, entity, example); + return executor.execute(boundedContext, update); + } + + @Override + public int insertOrUpdate(BoundedContext boundedContext, E entity) { + Assert.notNull(entity, "The entity cannot be null!"); + Operation operation = executor.buildInsertOrUpdate(boundedContext, entity); + return executor.execute(boundedContext, operation); + } + + @Override + public int delete(BoundedContext boundedContext, E entity) { + Assert.notNull(entity, "The entity cannot be null!"); + Delete delete = executor.buildDelete(boundedContext, entity); + return executor.execute(boundedContext, delete); + } + + @Override + public int deleteByPrimaryKey(BoundedContext boundedContext, PK primaryKey) { + Assert.notNull(primaryKey, "The primaryKey cannot be null!"); + Delete delete = executor.buildDeleteByPK(boundedContext, primaryKey); + return executor.execute(boundedContext, delete); + } + + @Override + public int deleteByExample(BoundedContext boundedContext, Example example) { + Assert.notNull(example, "The example cannot be null!"); + Delete delete = executor.buildDelete(boundedContext, example); + return executor.execute(boundedContext, delete); + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/repository/ConfiguredRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/repository/ConfiguredRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..dca90ea6e07b5f38f951b69226fb942f2df469c3 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/repository/ConfiguredRepository.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.repository; + +import com.gitee.dorive.core.entity.PropertyChain; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.OrderBy; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.impl.binder.ContextBinder; +import com.gitee.dorive.core.impl.binder.PropertyBinder; +import com.gitee.dorive.core.impl.resolver.BinderResolver; +import com.gitee.dorive.core.impl.resolver.PropertyResolver; +import com.gitee.dorive.core.api.MetadataHolder; +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.core.entity.BoundedContext; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = false) +public class ConfiguredRepository extends ProxyRepository implements MetadataHolder { + + protected String accessPath; + protected boolean aggregateRoot; + protected boolean aggregated; + protected PropertyChain anchorPoint; + protected PropertyResolver propertyResolver; + protected OrderBy defaultOrderBy; + protected String fieldPrefix; + protected BinderResolver binderResolver; + protected boolean boundEntity; + + @Override + public List selectByExample(BoundedContext boundedContext, Example example) { + if (example.isEmptyQuery()) { + return Collections.emptyList(); + } + if (example.getOrderBy() == null) { + example.setOrderBy(defaultOrderBy); + } + return super.selectByExample(boundedContext, example); + } + + @Override + public Page selectPageByExample(BoundedContext boundedContext, Example example) { + if (example.isEmptyQuery()) { + Page page = example.getPage(); + return page != null ? page : new Page<>(); + } + if (example.getOrderBy() == null) { + example.setOrderBy(defaultOrderBy); + } + return super.selectPageByExample(boundedContext, example); + } + + @Override + public Result selectResultByExample(BoundedContext boundedContext, Example example) { + if (example.isEmptyQuery()) { + Page page = example.getPage(); + return page != null ? new Result<>(page) : new Result<>(); + } + if (example.getOrderBy() == null) { + example.setOrderBy(defaultOrderBy); + } + return super.selectResultByExample(boundedContext, example); + } + + @Override + public int updateByExample(BoundedContext boundedContext, Object entity, Example example) { + if (example.isEmptyQuery()) { + return 0; + } + return super.updateByExample(boundedContext, entity, example); + } + + @Override + public int deleteByExample(BoundedContext boundedContext, Example example) { + if (example.isEmptyQuery()) { + return 0; + } + return super.deleteByExample(boundedContext, example); + } + + @Override + public Object getMetadata() { + AbstractRepository proxyRepository = getProxyRepository(); + if (proxyRepository instanceof MetadataHolder) { + return ((MetadataHolder) proxyRepository).getMetadata(); + } + return null; + } + + public boolean matchKeys(BoundedContext boundedContext) { + String[] matchKeys = entityDefinition.getMatchKeys(); + if (matchKeys == null || matchKeys.length == 0) { + return true; + } + for (String matchKey : matchKeys) { + if (boundedContext.containsKey(matchKey)) { + return true; + } + } + return false; + } + + public Example newExampleByContext(BoundedContext boundedContext, Object rootEntity) { + Example example = new Example(); + for (PropertyBinder propertyBinder : binderResolver.getPropertyBinders()) { + String alias = propertyBinder.getBindingDefinition().getAlias(); + Object boundValue = propertyBinder.getBoundValue(boundedContext, rootEntity); + if (boundValue instanceof Collection) { + boundValue = !((Collection) boundValue).isEmpty() ? boundValue : null; + } + if (boundValue != null) { + boundValue = propertyBinder.input(boundedContext, boundValue); + example.eq(alias, boundValue); + } else { + example.getCriteria().clear(); + break; + } + } + if (example.isDirtyQuery()) { + for (ContextBinder contextBinder : binderResolver.getContextBinders()) { + String alias = contextBinder.getBindingDefinition().getAlias(); + Object boundValue = contextBinder.getBoundValue(boundedContext, rootEntity); + if (boundValue != null) { + example.eq(alias, boundValue); + } + } + } + return example; + } + + public Object getPrimaryKey(Object entity) { + PropertyProxy primaryKeyProxy = entityElement.getPrimaryKeyProxy(); + return primaryKeyProxy.getValue(entity); + } + + public Object convertManyToOne(List entities) { + if (entityElement.isCollection()) { + return entities; + } else if (!entities.isEmpty()) { + return entities.get(0); + } + return null; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/repository/DefaultRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/repository/DefaultRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..66d63417624688974993921b701326dfb61737a3 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/repository/DefaultRepository.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.repository; + +import com.gitee.dorive.core.api.MetadataHolder; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class DefaultRepository extends AbstractRepository implements MetadataHolder { + + @Override + public Object getMetadata() { + if (executor instanceof MetadataHolder) { + return ((MetadataHolder) executor).getMetadata(); + } + return null; + } + +} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/ProxyRepository.java b/dorive-core/src/main/java/com/gitee/dorive/core/repository/ProxyRepository.java similarity index 48% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/ProxyRepository.java rename to dorive-core/src/main/java/com/gitee/dorive/core/repository/ProxyRepository.java index 7cba7484b539e9f8afc7bbcfce6a73f100499de0..942a7acc2221d99ae9773eabc7d6a7f942b81b89 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/ProxyRepository.java +++ b/dorive-core/src/main/java/com/gitee/dorive/core/repository/ProxyRepository.java @@ -1,6 +1,25 @@ -package com.gitee.spring.domain.core.repository; - -import com.gitee.spring.domain.core.entity.BoundedContext; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.repository; + +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.BoundedContext; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -16,29 +35,43 @@ public class ProxyRepository extends AbstractRepository { protected AbstractRepository proxyRepository; + public AbstractRepository getProxyRepository() { + if (proxyRepository instanceof ProxyRepository) { + return ((ProxyRepository) proxyRepository).getProxyRepository(); + } + return proxyRepository; + } + + public void setProxyRepository(AbstractRepository proxyRepository) { + if (this.proxyRepository instanceof ProxyRepository) { + ((ProxyRepository) this.proxyRepository).setProxyRepository(proxyRepository); + } + this.proxyRepository = proxyRepository; + } + @Override public Object selectByPrimaryKey(BoundedContext boundedContext, Object primaryKey) { return proxyRepository.selectByPrimaryKey(boundedContext, primaryKey); } @Override - public List selectByExample(BoundedContext boundedContext, Object example) { + public List selectByExample(BoundedContext boundedContext, Example example) { return proxyRepository.selectByExample(boundedContext, example); } @Override - public T selectPageByExample(BoundedContext boundedContext, Object example, Object page) { - return proxyRepository.selectPageByExample(boundedContext, example, page); + public Page selectPageByExample(BoundedContext boundedContext, Example example) { + return proxyRepository.selectPageByExample(boundedContext, example); } @Override - public int insert(BoundedContext boundedContext, Object entity) { - return proxyRepository.insert(boundedContext, entity); + public Result selectResultByExample(BoundedContext boundedContext, Example example) { + return proxyRepository.selectResultByExample(boundedContext, example); } @Override - public int updateSelective(BoundedContext boundedContext, Object entity) { - return proxyRepository.updateSelective(boundedContext, entity); + public int insert(BoundedContext boundedContext, Object entity) { + return proxyRepository.insert(boundedContext, entity); } @Override @@ -47,7 +80,7 @@ public class ProxyRepository extends AbstractRepository { } @Override - public int updateByExample(BoundedContext boundedContext, Object entity, Object example) { + public int updateByExample(BoundedContext boundedContext, Object entity, Example example) { return proxyRepository.updateByExample(boundedContext, entity, example); } @@ -67,7 +100,7 @@ public class ProxyRepository extends AbstractRepository { } @Override - public int deleteByExample(BoundedContext boundedContext, Object example) { + public int deleteByExample(BoundedContext boundedContext, Example example) { return proxyRepository.deleteByExample(boundedContext, example); } diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/PathUtils.java b/dorive-core/src/main/java/com/gitee/dorive/core/util/PathUtils.java similarity index 48% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/PathUtils.java rename to dorive-core/src/main/java/com/gitee/dorive/core/util/PathUtils.java index 4b4443ae2d8512830af2cf1507f139cb12dc9232..e6e9b17cb0e32cf2d509cd38322c045e7ad1f280 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/PathUtils.java +++ b/dorive-core/src/main/java/com/gitee/dorive/core/util/PathUtils.java @@ -1,4 +1,20 @@ -package com.gitee.spring.domain.core.utils; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.util; import cn.hutool.core.util.URLUtil; @@ -15,9 +31,9 @@ public class PathUtils { } public static String getAbsolutePath(String accessPath, String relativePath) { - accessPath = "https://spring-domain" + accessPath; + accessPath = "https://dorive" + accessPath; accessPath = URLUtil.completeUrl(accessPath, relativePath); - return accessPath.replace("https://spring-domain", ""); + return accessPath.replace("https://dorive", ""); } public static String getBelongPath(Set allAccessPath, String accessPath) { diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/util/ReflectUtils.java b/dorive-core/src/main/java/com/gitee/dorive/core/util/ReflectUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..2296f1fb75c3cc9b862e2350dd4b665d0d67cf89 --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/util/ReflectUtils.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.util; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.*; + +public class ReflectUtils { + + public static Class getFirstArgumentType(Class type) { + Type genericSuperclass = type.getGenericSuperclass(); + ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; + Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; + return (Class) actualTypeArgument; + } + + public static Object newInstance(Class type) { + return org.springframework.cglib.core.ReflectUtils.newInstance(type); + } + + public static List> getAllSuperclasses(Class type, Class ignoredType) { + List> superclasses = new ArrayList<>(); + Class superclass = type.getSuperclass(); + while (superclass != null) { + if (superclass != ignoredType) { + superclasses.add(superclass); + } + superclass = superclass.getSuperclass(); + } + Collections.reverse(superclasses); + return superclasses; + } + + public static Set getFieldNames(Class type) { + Set fieldNames = new LinkedHashSet<>(); + for (Field field : type.getDeclaredFields()) { + fieldNames.add(field.getName()); + } + return fieldNames; + } + +} diff --git a/dorive-core/src/main/java/com/gitee/dorive/core/util/StringUtils.java b/dorive-core/src/main/java/com/gitee/dorive/core/util/StringUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..f4fd48610f24d0cc255cc88cba3f267c24828c5a --- /dev/null +++ b/dorive-core/src/main/java/com/gitee/dorive/core/util/StringUtils.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.core.util; + +import cn.hutool.core.util.StrUtil; + +import java.util.Collection; + +public class StringUtils { + + public static String[] toUnderlineCase(String... columns) { + String[] newColumns = new String[columns.length]; + for (int index = 0; index < columns.length; index++) { + newColumns[index] = StrUtil.toUnderlineCase(columns[index]); + } + return newColumns; + } + + public static String[] toStringArray(Object object) { + if (object instanceof String) { + return new String[]{(String) object}; + + } else if (object instanceof String[]) { + return (String[]) object; + + } else if (object instanceof Collection) { + Collection collection = (Collection) object; + String[] stringArray = new String[collection.size()]; + int index = 0; + for (Object item : collection) { + stringArray[index++] = item.toString(); + } + return stringArray; + } + return null; + } + +} diff --git a/spring-domain-core/src/main/resources/META-INF/spring.factories b/dorive-core/src/main/resources/META-INF/spring.factories similarity index 52% rename from spring-domain-core/src/main/resources/META-INF/spring.factories rename to dorive-core/src/main/resources/META-INF/spring.factories index 8165946b32e78157ad79d14cf752b196acf283cf..54e414f0ab1098acb830f1c75e6b92f043cb68a2 100644 --- a/spring-domain-core/src/main/resources/META-INF/spring.factories +++ b/dorive-core/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gitee.spring.domain.core.config.DomainCoreConfiguration \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gitee.dorive.core.config.DomainCoreConfiguration \ No newline at end of file diff --git a/spring-domain-coating/pom.xml b/dorive-event/pom.xml similarity index 75% rename from spring-domain-coating/pom.xml rename to dorive-event/pom.xml index b2b60f7023fbbdaf0bf4346305a52e3926c55e71..f3b58fe435efa7bb902ed365cfe29cf99af02ad3 100644 --- a/spring-domain-coating/pom.xml +++ b/dorive-event/pom.xml @@ -5,15 +5,14 @@ 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 - spring-domain-coating - + dorive-event com.gitee.digital-engine - spring-domain-event + dorive-core ${project.version} diff --git a/dorive-event/src/main/java/com/gitee/dorive/event/annotation/EnableEvent.java b/dorive-event/src/main/java/com/gitee/dorive/event/annotation/EnableEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..02037fa87364b87e44474c48ea89c19dd9a62965 --- /dev/null +++ b/dorive-event/src/main/java/com/gitee/dorive/event/annotation/EnableEvent.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface EnableEvent { +} diff --git a/dorive-event/src/main/java/com/gitee/dorive/event/annotation/Listener.java b/dorive-event/src/main/java/com/gitee/dorive/event/annotation/Listener.java new file mode 100644 index 0000000000000000000000000000000000000000..bb41431e46fc1738d8c7f4b5fdf2a94ad54ca98e --- /dev/null +++ b/dorive-event/src/main/java/com/gitee/dorive/event/annotation/Listener.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Listener { + Class value(); +} diff --git a/dorive-event/src/main/java/com/gitee/dorive/event/api/EntityListener.java b/dorive-event/src/main/java/com/gitee/dorive/event/api/EntityListener.java new file mode 100644 index 0000000000000000000000000000000000000000..80f277a6fcb41ddea0ade45f74e5016fec7760e4 --- /dev/null +++ b/dorive-event/src/main/java/com/gitee/dorive/event/api/EntityListener.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.api; + +import com.gitee.dorive.event.entity.RepositoryEvent; + +public interface EntityListener { + + void onApplicationEvent(RepositoryEvent repositoryEvent); + +} diff --git a/dorive-event/src/main/java/com/gitee/dorive/event/config/DomainEventConfiguration.java b/dorive-event/src/main/java/com/gitee/dorive/event/config/DomainEventConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..a9de69173f3d1aac2cef1712a36f34fc2d23ff99 --- /dev/null +++ b/dorive-event/src/main/java/com/gitee/dorive/event/config/DomainEventConfiguration.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.config; + +import com.gitee.dorive.event.impl.RepositoryListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +@Order(-100) +@Configuration +public class DomainEventConfiguration { + + @Bean + public RepositoryListener repositoryListener() { + return new RepositoryListener(); + } + +} diff --git a/dorive-event/src/main/java/com/gitee/dorive/event/entity/RepositoryEvent.java b/dorive-event/src/main/java/com/gitee/dorive/event/entity/RepositoryEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..9864d185eb14979e96af80e153268ab64128e8db --- /dev/null +++ b/dorive-event/src/main/java/com/gitee/dorive/event/entity/RepositoryEvent.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.entity; + +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.event.repository.EventRepository; +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.ApplicationEvent; + +@Getter +@Setter +public class RepositoryEvent extends ApplicationEvent { + + private String methodName; + private BoundedContext boundedContext; + private Operation operation; + + public RepositoryEvent(EventRepository eventRepository) { + super(eventRepository); + } + +} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/listener/RepositoryListener.java b/dorive-event/src/main/java/com/gitee/dorive/event/impl/RepositoryListener.java similarity index 35% rename from spring-domain-event/src/main/java/com/gitee/spring/domain/event/listener/RepositoryListener.java rename to dorive-event/src/main/java/com/gitee/dorive/event/impl/RepositoryListener.java index 354f67c420fd62b7f2813b30e5e89b9bc79ae63b..f0e260a01571318304fb34adcd08869d9c0c34c1 100644 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/listener/RepositoryListener.java +++ b/dorive-event/src/main/java/com/gitee/dorive/event/impl/RepositoryListener.java @@ -1,10 +1,26 @@ -package com.gitee.spring.domain.event.listener; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.impl; -import com.gitee.spring.domain.event.annotation.EntityListener; -import com.gitee.spring.domain.event.api.EventListener; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.event.entity.RepositoryEvent; -import com.gitee.spring.domain.event.repository.EventRepository; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.event.annotation.Listener; +import com.gitee.dorive.event.api.EntityListener; +import com.gitee.dorive.event.entity.RepositoryEvent; +import com.gitee.dorive.event.repository.EventRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; @@ -22,8 +38,8 @@ import java.util.Map; @Slf4j public class RepositoryListener implements ApplicationListener, ApplicationContextAware, InitializingBean { - protected ApplicationContext applicationContext; - protected Map, List> classEventListenersMap = new LinkedHashMap<>(); + private ApplicationContext applicationContext; + private final Map, List> classEventListenersMap = new LinkedHashMap<>(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { @@ -32,15 +48,15 @@ public class RepositoryListener implements ApplicationListener, @Override public void afterPropertiesSet() { - Map entityListenerMap = applicationContext.getBeansOfType(EventListener.class); - List orderedEventListeners = new ArrayList<>(entityListenerMap.values()); - orderedEventListeners.sort(new AnnotationAwareOrderComparator()); - for (EventListener eventListener : orderedEventListeners) { - EntityListener entityListener = AnnotationUtils.getAnnotation(eventListener.getClass(), EntityListener.class); - if (entityListener != null) { - Class entityClass = entityListener.value(); - List eventListeners = classEventListenersMap.computeIfAbsent(entityClass, key -> new ArrayList<>()); - eventListeners.add(eventListener); + Map entityListenerMap = applicationContext.getBeansOfType(EntityListener.class); + List entityListeners = new ArrayList<>(entityListenerMap.values()); + entityListeners.sort(new AnnotationAwareOrderComparator()); + for (EntityListener entityListener : entityListeners) { + Listener listener = AnnotationUtils.getAnnotation(entityListener.getClass(), Listener.class); + if (listener != null) { + Class entityClass = listener.value(); + List existEntityListeners = classEventListenersMap.computeIfAbsent(entityClass, key -> new ArrayList<>()); + existEntityListeners.add(entityListener); } } } @@ -48,13 +64,13 @@ public class RepositoryListener implements ApplicationListener, @Override public void onApplicationEvent(RepositoryEvent event) { EventRepository eventRepository = (EventRepository) event.getSource(); - EntityDefinition entityDefinition = eventRepository.getEntityDefinition(); - Class entityClass = entityDefinition.getGenericEntityClass(); - List eventListeners = classEventListenersMap.get(entityClass); - if (eventListeners != null && !eventListeners.isEmpty()) { - for (EventListener eventListener : eventListeners) { + EntityElement entityElement = eventRepository.getEntityElement(); + Class entityClass = entityElement.getGenericEntityClass(); + List entityListeners = classEventListenersMap.get(entityClass); + if (entityListeners != null && !entityListeners.isEmpty()) { + for (EntityListener entityListener : entityListeners) { try { - eventListener.onApplicationEvent(event); + entityListener.onApplicationEvent(event); } catch (Exception e) { log.error("Exception occurred in event listening!", e); } diff --git a/dorive-event/src/main/java/com/gitee/dorive/event/repository/AbstractEventRepository.java b/dorive-event/src/main/java/com/gitee/dorive/event/repository/AbstractEventRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..2ec6ab0167a48a8e175a6de2a195186a00f590af --- /dev/null +++ b/dorive-event/src/main/java/com/gitee/dorive/event/repository/AbstractEventRepository.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.repository; + +import com.gitee.dorive.core.repository.AbstractGenericRepository; +import com.gitee.dorive.core.repository.AbstractRepository; +import com.gitee.dorive.core.repository.DefaultRepository; +import com.gitee.dorive.event.annotation.EnableEvent; +import org.springframework.core.annotation.AnnotationUtils; + +public abstract class AbstractEventRepository extends AbstractGenericRepository { + + protected boolean enableEvent; + + @Override + public void afterPropertiesSet() throws Exception { + EnableEvent enableEvent = AnnotationUtils.getAnnotation(this.getClass(), EnableEvent.class); + this.enableEvent = enableEvent != null; + super.afterPropertiesSet(); + } + + @Override + protected AbstractRepository postProcessRepository(AbstractRepository repository) { + if (enableEvent && (repository instanceof DefaultRepository)) { + DefaultRepository defaultRepository = (DefaultRepository) repository; + EventRepository eventRepository = new EventRepository(applicationContext); + eventRepository.setEntityElement(defaultRepository.getEntityElement()); + eventRepository.setEntityDefinition(defaultRepository.getEntityDefinition()); + eventRepository.setProxyRepository(repository); + return eventRepository; + } + return repository; + } + +} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/repository/EventRepository.java b/dorive-event/src/main/java/com/gitee/dorive/event/repository/EventRepository.java similarity index 50% rename from spring-domain-event/src/main/java/com/gitee/spring/domain/event/repository/EventRepository.java rename to dorive-event/src/main/java/com/gitee/dorive/event/repository/EventRepository.java index d81078182511c46024643a346eab47be8553a6eb..65b74f69e59a7d9090441eeddc47bb0d27106806 100644 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/repository/EventRepository.java +++ b/dorive-event/src/main/java/com/gitee/dorive/event/repository/EventRepository.java @@ -1,33 +1,49 @@ -package com.gitee.spring.domain.event.repository; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.event.repository; -import com.gitee.spring.domain.core.entity.*; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import com.gitee.spring.domain.event.entity.OperationType; -import com.gitee.spring.domain.event.entity.RepositoryEvent; -import lombok.Getter; -import lombok.Setter; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.operation.Delete; +import com.gitee.dorive.core.entity.operation.Insert; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.entity.operation.Update; +import com.gitee.dorive.core.repository.ProxyRepository; +import com.gitee.dorive.event.entity.RepositoryEvent; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; import org.springframework.context.ApplicationContext; -@Getter -@Setter -public class EventRepository extends ConfiguredRepository { +@Data +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class EventRepository extends ProxyRepository { protected ApplicationContext applicationContext; - public EventRepository(ConfiguredRepository configuredRepository, ApplicationContext applicationContext) { - super(configuredRepository); - this.applicationContext = applicationContext; - } - @Override public int insert(BoundedContext boundedContext, Object entity) { int count = super.insert(boundedContext, entity); if (count != 0) { RepositoryEvent repositoryEvent = new RepositoryEvent(this); repositoryEvent.setMethodName("insert"); - repositoryEvent.setOperationType(OperationType.INSERT); repositoryEvent.setBoundedContext(boundedContext); - repositoryEvent.setEntity(entity); + repositoryEvent.setOperation(new Insert(Operation.INSERT, entity)); applicationContext.publishEvent(repositoryEvent); } return count; @@ -39,24 +55,36 @@ public class EventRepository extends ConfiguredRepository { if (count != 0) { RepositoryEvent repositoryEvent = new RepositoryEvent(this); repositoryEvent.setMethodName("update"); - repositoryEvent.setOperationType(OperationType.UPDATE); repositoryEvent.setBoundedContext(boundedContext); - repositoryEvent.setEntity(entity); + repositoryEvent.setOperation(new Update(Operation.UPDATE, entity)); applicationContext.publishEvent(repositoryEvent); } return count; } @Override - public int updateByExample(BoundedContext boundedContext, Object entity, Object example) { + public int updateByExample(BoundedContext boundedContext, Object entity, Example example) { int count = super.updateByExample(boundedContext, entity, example); if (count != 0) { RepositoryEvent repositoryEvent = new RepositoryEvent(this); repositoryEvent.setMethodName("updateByExample"); - repositoryEvent.setOperationType(OperationType.UPDATE); repositoryEvent.setBoundedContext(boundedContext); - repositoryEvent.setEntity(entity); - repositoryEvent.setExample(example); + Update update = new Update(Operation.UPDATE, entity); + update.setExample(example); + repositoryEvent.setOperation(update); + applicationContext.publishEvent(repositoryEvent); + } + return count; + } + + @Override + public int insertOrUpdate(BoundedContext boundedContext, Object entity) { + int count = super.insertOrUpdate(boundedContext, entity); + if (count != 0) { + RepositoryEvent repositoryEvent = new RepositoryEvent(this); + repositoryEvent.setMethodName("insertOrUpdate"); + repositoryEvent.setBoundedContext(boundedContext); + repositoryEvent.setOperation(new Operation(Operation.INSERT_OR_UPDATE, entity)); applicationContext.publishEvent(repositoryEvent); } return count; @@ -68,9 +96,8 @@ public class EventRepository extends ConfiguredRepository { if (count != 0) { RepositoryEvent repositoryEvent = new RepositoryEvent(this); repositoryEvent.setMethodName("delete"); - repositoryEvent.setOperationType(OperationType.DELETE); repositoryEvent.setBoundedContext(boundedContext); - repositoryEvent.setEntity(entity); + repositoryEvent.setOperation(new Delete(Operation.DELETE, entity)); applicationContext.publishEvent(repositoryEvent); } return count; @@ -82,23 +109,25 @@ public class EventRepository extends ConfiguredRepository { if (count != 0) { RepositoryEvent repositoryEvent = new RepositoryEvent(this); repositoryEvent.setMethodName("deleteByPrimaryKey"); - repositoryEvent.setOperationType(OperationType.DELETE); repositoryEvent.setBoundedContext(boundedContext); - repositoryEvent.setPrimaryKey(primaryKey); + Delete delete = new Delete(Operation.DELETE, null); + delete.setPrimaryKey(primaryKey); + repositoryEvent.setOperation(delete); applicationContext.publishEvent(repositoryEvent); } return count; } @Override - public int deleteByExample(BoundedContext boundedContext, Object example) { + public int deleteByExample(BoundedContext boundedContext, Example example) { int count = super.deleteByExample(boundedContext, example); if (count != 0) { RepositoryEvent repositoryEvent = new RepositoryEvent(this); repositoryEvent.setMethodName("deleteByExample"); - repositoryEvent.setOperationType(OperationType.DELETE); repositoryEvent.setBoundedContext(boundedContext); - repositoryEvent.setExample(example); + Delete delete = new Delete(Operation.DELETE, null); + delete.setExample(example); + repositoryEvent.setOperation(delete); applicationContext.publishEvent(repositoryEvent); } return count; diff --git a/spring-domain-event/src/main/resources/META-INF/spring.factories b/dorive-event/src/main/resources/META-INF/spring.factories similarity index 51% rename from spring-domain-event/src/main/resources/META-INF/spring.factories rename to dorive-event/src/main/resources/META-INF/spring.factories index 8745411b983547ed865d8c32d138e04c0aa6de79..0ae90702cdf029edb2ac74475b28c5c36fbd706a 100644 --- a/spring-domain-event/src/main/resources/META-INF/spring.factories +++ b/dorive-event/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gitee.spring.domain.event.config.DomainEventConfiguration \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gitee.dorive.event.config.DomainEventConfiguration \ No newline at end of file diff --git a/spring-domain-injection/pom.xml b/dorive-injection/pom.xml similarity index 88% rename from spring-domain-injection/pom.xml rename to dorive-injection/pom.xml index 23f5b78866834c1cf0104883b412aec539e06971..251e134550e2d64363bdc97b3698362cc302afed 100644 --- a/spring-domain-injection/pom.xml +++ b/dorive-injection/pom.xml @@ -5,11 +5,10 @@ 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 - spring-domain-injection - + dorive-injection org.springframework.boot diff --git a/dorive-injection/src/main/java/com/gitee/dorive/injection/annotation/Root.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/annotation/Root.java new file mode 100644 index 0000000000000000000000000000000000000000..e33b7721e780776dd1c2ecc4d9ae8386a43ed166 --- /dev/null +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/annotation/Root.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.annotation; + +import java.lang.annotation.*; + +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Root { +} diff --git a/dorive-injection/src/main/java/com/gitee/dorive/injection/api/TypeDomainResolver.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/api/TypeDomainResolver.java new file mode 100644 index 0000000000000000000000000000000000000000..81cae8b7a96c4fa2142d249652b4b1723832a69b --- /dev/null +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/api/TypeDomainResolver.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.api; + +import com.gitee.dorive.injection.entity.DomainDefinition; + +public interface TypeDomainResolver { + + boolean isUnderScanPackage(Class typeToMatch); + + DomainDefinition matchDomainDefinition(Class typeToMatch); + + void checkDomain(Class targetType, Class injectedType); + + void checkDomainProtection(Class targetType); + +} diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/config/DomainInjectionConfiguration.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/config/DomainInjectionConfiguration.java similarity index 67% rename from spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/config/DomainInjectionConfiguration.java rename to dorive-injection/src/main/java/com/gitee/dorive/injection/config/DomainInjectionConfiguration.java index 2a253e0448460ccd85fd4b0b7be3d43682eeb098..533bdf1e2f93577a6d3ce2477515af444594b19c 100644 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/config/DomainInjectionConfiguration.java +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/config/DomainInjectionConfiguration.java @@ -1,12 +1,28 @@ -package com.gitee.spring.domain.injection.config; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.config; import cn.hutool.core.lang.Assert; -import com.gitee.spring.domain.injection.api.TypeDomainResolver; -import com.gitee.spring.domain.injection.entity.DomainDefinition; -import com.gitee.spring.domain.injection.impl.DefaultTypeDomainResolver; -import com.gitee.spring.domain.injection.spring.LimitedAutowiredBeanPostProcessor; -import com.gitee.spring.domain.injection.spring.LimitedCglibSubclassingInstantiationStrategy; -import com.gitee.spring.domain.injection.spring.LimitedRootInitializingBean; +import com.gitee.dorive.injection.impl.DefaultTypeDomainResolver; +import com.gitee.dorive.injection.spring.LimitedAutowiredBeanPostProcessor; +import com.gitee.dorive.injection.spring.LimitedCglibSubclassingInstantiationStrategy; +import com.gitee.dorive.injection.spring.LimitedRootInitializingBean; +import com.gitee.dorive.injection.api.TypeDomainResolver; +import com.gitee.dorive.injection.entity.DomainDefinition; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; diff --git a/dorive-injection/src/main/java/com/gitee/dorive/injection/entity/DomainDefinition.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/entity/DomainDefinition.java new file mode 100644 index 0000000000000000000000000000000000000000..7db4652f06d270b2b0808713ee9192d1d57852b3 --- /dev/null +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/entity/DomainDefinition.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class DomainDefinition { + private String name; + private String pattern; + private String protect; +} diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/impl/DefaultTypeDomainResolver.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/impl/DefaultTypeDomainResolver.java similarity index 76% rename from spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/impl/DefaultTypeDomainResolver.java rename to dorive-injection/src/main/java/com/gitee/dorive/injection/impl/DefaultTypeDomainResolver.java index f3c8f3e971f8bca77286a023a9eb76feb50ac807..39538969df5b7d1a1f1f149a905d8d0b1012334f 100644 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/impl/DefaultTypeDomainResolver.java +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/impl/DefaultTypeDomainResolver.java @@ -1,9 +1,25 @@ -package com.gitee.spring.domain.injection.impl; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.impl; import cn.hutool.core.collection.CollUtil; -import com.gitee.spring.domain.injection.annotation.Root; -import com.gitee.spring.domain.injection.api.TypeDomainResolver; -import com.gitee.spring.domain.injection.entity.DomainDefinition; +import com.gitee.dorive.injection.annotation.Root; +import com.gitee.dorive.injection.api.TypeDomainResolver; +import com.gitee.dorive.injection.entity.DomainDefinition; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.BeanCreationException; import org.springframework.core.annotation.AnnotationUtils; diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedAutowiredBeanPostProcessor.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedAutowiredBeanPostProcessor.java similarity index 79% rename from spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedAutowiredBeanPostProcessor.java rename to dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedAutowiredBeanPostProcessor.java index f0b4a29bbac31d5a490723ffd246e313d4f31766..becd963ec69847e46c296ffbfd8e7131a4f573b1 100644 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedAutowiredBeanPostProcessor.java +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedAutowiredBeanPostProcessor.java @@ -1,6 +1,22 @@ -package com.gitee.spring.domain.injection.spring; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.spring; -import com.gitee.spring.domain.injection.api.TypeDomainResolver; +import com.gitee.dorive.injection.api.TypeDomainResolver; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedCglibSubclassingInstantiationStrategy.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedCglibSubclassingInstantiationStrategy.java similarity index 65% rename from spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedCglibSubclassingInstantiationStrategy.java rename to dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedCglibSubclassingInstantiationStrategy.java index c6a7f7c8c4b3cc09ca9b79d1d10e8e27d7594e44..2282142897dc883d1ed5b7ed70ba349e50e30e4c 100644 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedCglibSubclassingInstantiationStrategy.java +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedCglibSubclassingInstantiationStrategy.java @@ -1,6 +1,22 @@ -package com.gitee.spring.domain.injection.spring; - -import com.gitee.spring.domain.injection.api.TypeDomainResolver; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.spring; + +import com.gitee.dorive.injection.api.TypeDomainResolver; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.CglibSubclassingInstantiationStrategy; import org.springframework.beans.factory.support.RootBeanDefinition; diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedRootInitializingBean.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedRootInitializingBean.java similarity index 53% rename from spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedRootInitializingBean.java rename to dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedRootInitializingBean.java index fed0758c85e88e40cd27816b25e8ce6bb4054fbe..cbaf6f3eca467c85007f97d67d4a558764599057 100644 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/spring/LimitedRootInitializingBean.java +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/spring/LimitedRootInitializingBean.java @@ -1,8 +1,24 @@ -package com.gitee.spring.domain.injection.spring; - -import com.gitee.spring.domain.injection.annotation.Root; -import com.gitee.spring.domain.injection.api.TypeDomainResolver; -import com.gitee.spring.domain.injection.utils.AopUtils; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.spring; + +import com.gitee.dorive.injection.annotation.Root; +import com.gitee.dorive.injection.api.TypeDomainResolver; +import com.gitee.dorive.injection.utils.AopUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/utils/AopUtils.java b/dorive-injection/src/main/java/com/gitee/dorive/injection/utils/AopUtils.java similarity index 51% rename from spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/utils/AopUtils.java rename to dorive-injection/src/main/java/com/gitee/dorive/injection/utils/AopUtils.java index fa3751530e1bb396ab38d6e48568b3dad102e56f..45b73c03a144516b5465e8d37a1d1694d269b19c 100644 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/utils/AopUtils.java +++ b/dorive-injection/src/main/java/com/gitee/dorive/injection/utils/AopUtils.java @@ -1,4 +1,20 @@ -package com.gitee.spring.domain.injection.utils; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.dorive.injection.utils; import java.lang.annotation.Annotation; diff --git a/spring-domain-injection/src/main/resources/META-INF/spring.factories b/dorive-injection/src/main/resources/META-INF/spring.factories similarity index 48% rename from spring-domain-injection/src/main/resources/META-INF/spring.factories rename to dorive-injection/src/main/resources/META-INF/spring.factories index 3be8fa9800d96f78b8d0a80bc65d0f55829c6539..f95c7848bbdd1d6090ee490ba6837574a2d0aa75 100644 --- a/spring-domain-injection/src/main/resources/META-INF/spring.factories +++ b/dorive-injection/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gitee.spring.domain.injection.config.DomainInjectionConfiguration \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gitee.dorive.injection.config.DomainInjectionConfiguration \ No newline at end of file diff --git a/spring-domain-web/pom.xml b/dorive-proxy/pom.xml similarity index 57% rename from spring-domain-web/pom.xml rename to dorive-proxy/pom.xml index 3cb5e67abd50041700a39d055b6b3d2355f42581..8b113b6bfec937dda2d122c1e9f914c5146c28ff 100644 --- a/spring-domain-web/pom.xml +++ b/dorive-proxy/pom.xml @@ -5,16 +5,18 @@ 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 - spring-domain-web - + dorive-proxy - com.gitee.digital-engine - spring-domain-coating - ${project.version} + org.javassist + javassist + + + org.apache.commons + commons-lang3 \ No newline at end of file diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/AbstractCompiler.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/AbstractCompiler.java similarity index 96% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/AbstractCompiler.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/AbstractCompiler.java index fd9a90e3b6d13b9fa8ab9c628b5a276a97f5b6f9..15e3540dc1a98f413814ac5b0f9c77060acac23d 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/AbstractCompiler.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/AbstractCompiler.java @@ -14,9 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.compile; - -import com.gitee.spring.domain.core.api.ProxyCompiler; +package com.gitee.dorive.proxy; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/ClassLoaderUtils.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/ClassLoaderUtils.java similarity index 99% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/ClassLoaderUtils.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/ClassLoaderUtils.java index 9e22b52e65b47aa07415b07f58c5ffd952f6b558..a9afc3bb9ae541e968b44e5cedf01fb59ce4743c 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/ClassLoaderUtils.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/ClassLoaderUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.compile; +package com.gitee.dorive.proxy; import java.lang.reflect.Array; import java.util.*; diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/ClassUtils.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/ClassUtils.java similarity index 99% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/ClassUtils.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/ClassUtils.java index 758fa38371f5fdddefb7941592a4be12117db15b..83881600410de0308221270658b583126a753676 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/ClassUtils.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/ClassUtils.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.compile; +package com.gitee.dorive.proxy; import org.apache.commons.lang3.StringUtils; diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/CtClassBuilder.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/CtClassBuilder.java similarity index 99% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/CtClassBuilder.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/CtClassBuilder.java index e8ec9bfb7cffd1c0dadd20034ad94848e6cfa2e7..534855e407f437ca7d9f54755040dd893967bfb1 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/CtClassBuilder.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/CtClassBuilder.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.compile; +package com.gitee.dorive.proxy; import javassist.*; diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/JavassistCompiler.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/JavassistCompiler.java similarity index 98% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/JavassistCompiler.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/JavassistCompiler.java index 0b627aa6b967e2a23e74a595cc00cffb2e4ff070..827d40a6213cbea422036553f8a16c18b4712577 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/JavassistCompiler.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/JavassistCompiler.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.compile; +package com.gitee.dorive.proxy; import javassist.CtClass; diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/JdkCompiler.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/JdkCompiler.java similarity index 99% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/JdkCompiler.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/JdkCompiler.java index ad8f6e1c34af930cefb3f5e94e5a7eec1abb508a..cc9ce6576beda1e1d8c1c4a70aa133a57dcbf030 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/compile/JdkCompiler.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/JdkCompiler.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.compile; +package com.gitee.dorive.proxy; import javax.tools.*; import javax.tools.JavaFileObject.Kind; diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/ProxyCompiler.java b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/ProxyCompiler.java similarity index 96% rename from spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/ProxyCompiler.java rename to dorive-proxy/src/main/java/com/gitee/dorive/proxy/ProxyCompiler.java index 7d208ae68461e572e26daf5c0304014d51215cb0..f40ce6d8349beaf5f6364d4e1b13c15e327eba0c 100644 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/ProxyCompiler.java +++ b/dorive-proxy/src/main/java/com/gitee/dorive/proxy/ProxyCompiler.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitee.spring.domain.core.api; +package com.gitee.dorive.proxy; public interface ProxyCompiler { diff --git a/pom.xml b/pom.xml index 4e9aa006bb7ebfc92475f51599748da143c3943a..dad4509c64f5d66cd7aa87d408ea05a0f123bf70 100644 --- a/pom.xml +++ b/pom.xml @@ -4,17 +4,17 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 pom - spring-domain-injection - spring-domain-core - spring-domain-event - spring-domain-coating - spring-domain-web - spring-boot-starter-domain + dorive-injection + dorive-proxy + dorive-core + dorive-event + dorive-coating + spring-boot-starter-dorive diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/annotation/RootRepository.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/annotation/RootRepository.java deleted file mode 100644 index 8e7a4c33e372fbbfae0bdf52cb3b9115f78f16d7..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/annotation/RootRepository.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.gitee.spring.boot.starter.domain.annotation; - -import com.gitee.spring.domain.coating.annotation.CoatingScan; -import com.gitee.spring.domain.core.annotation.Repository; -import com.gitee.spring.domain.event.annotation.EnableEvent; -import com.gitee.spring.domain.injection.annotation.Root; -import com.gitee.spring.domain.web.annotation.EnableWeb; -import org.springframework.core.annotation.AliasFor; - -import java.lang.annotation.*; - -@Root -@Repository -@EnableEvent -@CoatingScan -@EnableWeb -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface RootRepository { - - @AliasFor(annotation = Repository.class) - String value() default ""; - - @AliasFor(annotation = Repository.class) - String name() default ""; - - @AliasFor(annotation = CoatingScan.class, attribute = "value") - String[] scanPackages() default {}; - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/api/ExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/api/ExampleBuilder.java deleted file mode 100644 index e906227bd3021adb76bccf0a3f592030c902027b..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/api/ExampleBuilder.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.gitee.spring.boot.starter.domain.api; - -public interface ExampleBuilder { - - void appendCriterion(Object example, String fieldName, Object fieldValue); - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/EQExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/EQExampleBuilder.java deleted file mode 100644 index a79147c46fd6dbb0a73d4b24ee15d5755daa34fa..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/EQExampleBuilder.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -import java.util.Collection; - -public class EQExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - if (fieldValue instanceof Collection) { - queryWrapper.in(fieldName, (Collection) fieldValue); - } else { - queryWrapper.eq(fieldName, fieldValue); - } - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/GEExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/GEExampleBuilder.java deleted file mode 100644 index 21ca12830e87ad7ca10e729321ccaf2d6af322af..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/GEExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class GEExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.ge(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/GTExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/GTExampleBuilder.java deleted file mode 100644 index a42a873c58349c4ba791f7e373324652f3ede5a4..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/GTExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class GTExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.gt(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/InExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/InExampleBuilder.java deleted file mode 100644 index fe2df5503a6a459be91d8eae260577e327cdf7e9..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/InExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class InExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.in(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/IsNotNullExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/IsNotNullExampleBuilder.java deleted file mode 100644 index 445372dc332a1ec3981ad92df58f03109faabf33..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/IsNotNullExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class IsNotNullExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.isNotNull(fieldName); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/IsNullExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/IsNullExampleBuilder.java deleted file mode 100644 index 449e109888e6e7a5337cf87b70f7f929e685aa7d..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/IsNullExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class IsNullExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.isNull(fieldName); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LEExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LEExampleBuilder.java deleted file mode 100644 index cdcb5facbde052b4312e16346b8991f6467787a2..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LEExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class LEExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.le(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LTExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LTExampleBuilder.java deleted file mode 100644 index 1779034d90f90278ffb3d867d35adb4980ffe3d8..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LTExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class LTExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.lt(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LikeExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LikeExampleBuilder.java deleted file mode 100644 index 03cc5b3f3a70f6290bc18838875f689caa0b5572..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/LikeExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class LikeExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.like(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NEExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NEExampleBuilder.java deleted file mode 100644 index 9415c5a127c8e993b4c5e32fa97ffafa34af7ec3..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NEExampleBuilder.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -import java.util.Collection; - -public class NEExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - if (fieldValue instanceof Collection) { - queryWrapper.notIn(fieldName, (Collection) fieldValue); - } else { - queryWrapper.ne(fieldName, fieldValue); - } - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NotInExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NotInExampleBuilder.java deleted file mode 100644 index 83fde885fc56c8563e6d7fad947ad23a578d9a6d..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NotInExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class NotInExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.notIn(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NotLikeExampleBuilder.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NotLikeExampleBuilder.java deleted file mode 100644 index 721dec2f93c456216fd5eb42782872b683addf54..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/builder/NotLikeExampleBuilder.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.gitee.spring.boot.starter.domain.builder; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; - -public class NotLikeExampleBuilder implements ExampleBuilder { - - @Override - public void appendCriterion(Object example, String fieldName, Object fieldValue) { - QueryWrapper queryWrapper = (QueryWrapper) example; - queryWrapper.notLike(fieldName, fieldValue); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusEntityMapper.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusEntityMapper.java deleted file mode 100644 index 6d79c52a9debeaaf32f1fd9d0ed957871f6d8486..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusEntityMapper.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.gitee.spring.boot.starter.domain.repository; - -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.gitee.spring.boot.starter.domain.api.ExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.EQExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.GEExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.GTExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.InExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.IsNotNullExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.IsNullExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.LEExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.LTExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.LikeExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.NEExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.NotInExampleBuilder; -import com.gitee.spring.boot.starter.domain.builder.NotLikeExampleBuilder; -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.constants.Operator; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityCriterion; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.entity.EntityExample; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class MybatisPlusEntityMapper implements EntityMapper { - - public static Map operatorExampleBuilderMap = new ConcurrentHashMap<>(); - protected EntityDefinition entityDefinition; - - static { - operatorExampleBuilderMap.put(Operator.EQ, new EQExampleBuilder()); - operatorExampleBuilderMap.put(Operator.NE, new NEExampleBuilder()); - operatorExampleBuilderMap.put(Operator.IN, new InExampleBuilder()); - operatorExampleBuilderMap.put(Operator.NOT_IN, new NotInExampleBuilder()); - operatorExampleBuilderMap.put(Operator.IS_NULL, new IsNullExampleBuilder()); - operatorExampleBuilderMap.put(Operator.IS_NOT_NULL, new IsNotNullExampleBuilder()); - operatorExampleBuilderMap.put(Operator.LIKE, new LikeExampleBuilder()); - operatorExampleBuilderMap.put(Operator.NOT_LIKE, new NotLikeExampleBuilder()); - operatorExampleBuilderMap.put(Operator.GT, new GTExampleBuilder()); - operatorExampleBuilderMap.put(Operator.GE, new GEExampleBuilder()); - operatorExampleBuilderMap.put(Operator.LT, new LTExampleBuilder()); - operatorExampleBuilderMap.put(Operator.LE, new LEExampleBuilder()); - } - - public MybatisPlusEntityMapper(EntityDefinition entityDefinition) { - this.entityDefinition = entityDefinition; - } - - @Override - public Object newPage(Integer pageNum, Integer pageSize) { - return new Page<>(pageNum, pageSize); - } - - @Override - @SuppressWarnings("unchecked") - public List getDataFromPage(Object dataPage) { - return ((IPage) dataPage).getRecords(); - } - - @Override - public Object newPageOfEntities(Object dataPage, List entities) { - IPage page = (IPage) dataPage; - IPage newPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal()); - newPage.setRecords(entities); - return newPage; - } - - @Override - public Object buildExample(BoundedContext boundedContext, EntityExample entityExample) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - String[] selectColumns = entityExample.getSelectColumns(); - if (selectColumns != null) { - queryWrapper.select(selectColumns); - } - for (EntityCriterion entityCriterion : entityExample.getEntityCriteria()) { - String fieldName = entityCriterion.getFieldName(); - String operator = entityCriterion.getOperator(); - Object fieldValue = entityCriterion.getFieldValue(); - ExampleBuilder exampleBuilder = operatorExampleBuilderMap.get(operator); - exampleBuilder.appendCriterion(queryWrapper, StrUtil.toUnderlineCase(fieldName), fieldValue); - } - String[] orderBy; - if (entityExample.getOrderBy() != null) { - orderBy = entityExample.getOrderBy(); - } else { - orderBy = entityDefinition.getOrderBy(); - } - String sort; - if (entityExample.getSort() != null) { - sort = entityExample.getSort(); - } else { - sort = entityDefinition.getSort(); - } - if (orderBy != null && sort != null) { - if ("asc".equals(sort)) { - queryWrapper.orderByAsc(orderBy); - } else if ("desc".equals(sort)) { - queryWrapper.orderByDesc(orderBy); - } - } - return queryWrapper; - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusGenericRepository.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusGenericRepository.java deleted file mode 100644 index 34d135604c215df8e2b184b0171d1cb41846ccb5..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusGenericRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.gitee.spring.boot.starter.domain.repository; - -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.repository.AbstractRepository; -import com.gitee.spring.domain.web.repository.AbstractWebRepository; - -import java.io.Serializable; - -public class MybatisPlusGenericRepository extends AbstractWebRepository { - - @Override - protected EntityMapper newEntityMapper(EntityDefinition entityDefinition) { - return new MybatisPlusEntityMapper(entityDefinition); - } - - @Override - protected AbstractRepository newRepository(EntityDefinition entityDefinition) { - return new MybatisPlusRepository(entityDefinition); - } - -} diff --git a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusRepository.java b/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusRepository.java deleted file mode 100644 index 7920c1e8c0e0f68203fe257ea768d540758eef64..0000000000000000000000000000000000000000 --- a/spring-boot-starter-domain/src/main/java/com/gitee/spring/boot/starter/domain/repository/MybatisPlusRepository.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.gitee.spring.boot.starter.domain.repository; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.lang.Pair; -import cn.hutool.core.util.ReflectUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.repository.AbstractRepository; - -import java.io.Serializable; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -@SuppressWarnings("unchecked") -public class MybatisPlusRepository extends AbstractRepository { - - protected EntityDefinition entityDefinition; - protected BaseMapper baseMapper; - protected List> fieldColumnPairs; - - public MybatisPlusRepository(EntityDefinition entityDefinition) { - this.entityDefinition = entityDefinition; - this.baseMapper = (BaseMapper) entityDefinition.getMapper(); - Class pojoClass = entityDefinition.getPojoClass(); - if (pojoClass != null) { - this.fieldColumnPairs = new ArrayList<>(); - for (Field field : ReflectUtil.getFields(pojoClass)) { - boolean isTableId = field.isAnnotationPresent(TableId.class); - String fieldName = field.getName(); - if (isTableId || "id".equals(fieldName)) { - continue; - } - TableField tableField = field.getAnnotation(TableField.class); - String columnName = tableField != null ? tableField.value() : StrUtil.toUnderlineCase(fieldName); - fieldColumnPairs.add(new Pair<>(fieldName, columnName)); - } - } - } - - @Override - public Object selectByPrimaryKey(BoundedContext boundedContext, Object primaryKey) { - return baseMapper.selectById((Serializable) primaryKey); - } - - @Override - public List selectByExample(BoundedContext boundedContext, Object example) { - if (example instanceof Wrapper) { - return baseMapper.selectList((Wrapper) example); - - } else if (example instanceof Map) { - return baseMapper.selectByMap((Map) example); - } - return null; - } - - @Override - public T selectPageByExample(BoundedContext boundedContext, Object example, Object page) { - return (T) baseMapper.selectPage((IPage) page, (Wrapper) example); - } - - @Override - public int insert(BoundedContext boundedContext, Object entity) { - return baseMapper.insert(entity); - } - - @Override - public int updateSelective(BoundedContext boundedContext, Object entity) { - return baseMapper.updateById(entity); - } - - @Override - public int update(BoundedContext boundedContext, Object entity) { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - if (primaryKey != null) { - Set fieldNames = (Set) boundedContext.get("#forceUpdate"); - if (fieldNames != null && !fieldNames.isEmpty()) { - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", primaryKey); - for (Pair fieldColumnPair : fieldColumnPairs) { - String fieldName = fieldColumnPair.getKey(); - Object fieldValue = BeanUtil.getFieldValue(entity, fieldName); - if (fieldValue != null || fieldNames.contains(fieldName)) { - updateWrapper.set(true, fieldColumnPair.getValue(), fieldValue); - } - } - return baseMapper.update(null, updateWrapper); - } else { - return baseMapper.updateById(entity); - } - } - return 0; - } - - @Override - public int updateByExample(BoundedContext boundedContext, Object entity, Object example) { - return baseMapper.update(entity, (Wrapper) example); - } - - @Override - public int insertOrUpdate(BoundedContext boundedContext, Object entity) { - throw new RuntimeException("This method is not supported!"); - } - - @Override - public int delete(BoundedContext boundedContext, Object entity) { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - return deleteByPrimaryKey(boundedContext, primaryKey); - } - - @Override - public int deleteByPrimaryKey(BoundedContext boundedContext, Object primaryKey) { - return baseMapper.deleteById((Serializable) primaryKey); - } - - @Override - public int deleteByExample(BoundedContext boundedContext, Object example) { - return baseMapper.delete((Wrapper) example); - } - -} diff --git a/spring-boot-starter-domain/pom.xml b/spring-boot-starter-dorive/pom.xml similarity index 50% rename from spring-boot-starter-domain/pom.xml rename to spring-boot-starter-dorive/pom.xml index 6fa424978d06b60fe7993b5ce7983e48ffc249ec..9febfaf70b461bd79f7cfd640dab45c2d6e7527e 100644 --- a/spring-boot-starter-domain/pom.xml +++ b/spring-boot-starter-dorive/pom.xml @@ -5,35 +5,19 @@ 4.0.0 com.gitee.digital-engine - spring-domain - 2.8.3 + dorive + 3.0.0 - spring-boot-starter-domain - + spring-boot-starter-dorive com.gitee.digital-engine - spring-domain-injection + dorive-injection ${project.version} com.gitee.digital-engine - spring-domain-core - ${project.version} - - - com.gitee.digital-engine - spring-domain-event - ${project.version} - - - com.gitee.digital-engine - spring-domain-coating - ${project.version} - - - com.gitee.digital-engine - spring-domain-web + dorive-coating ${project.version} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/annotation/RootRepository.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/annotation/RootRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..55f9e0b1015dcde1c9f2cb067782d6e3a8b3b639 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/annotation/RootRepository.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.annotation; + +import com.gitee.dorive.core.annotation.Repository; +import com.gitee.dorive.injection.annotation.Root; +import org.springframework.core.annotation.AliasFor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Root +@Repository +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface RootRepository { + + @AliasFor(annotation = Repository.class) + String value() default ""; + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/api/CriterionAppender.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/api/CriterionAppender.java new file mode 100644 index 0000000000000000000000000000000000000000..584164fce3e74300239bdf1c56ff5baddb6944c2 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/api/CriterionAppender.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.api; + +import com.baomidou.mybatisplus.core.conditions.AbstractWrapper; + +public interface CriterionAppender { + + void appendCriterion(AbstractWrapper abstractWrapper, String property, Object value); + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/config/EnvironmentProcessor.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/config/EnvironmentProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..ded212338c51dca61406ea8dd1f2fd13ee1302b1 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/config/EnvironmentProcessor.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.gitee.spring.boot.starter.dorive.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.Ordered; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.PropertiesPropertySource; + +import java.util.Properties; + +public class EnvironmentProcessor implements EnvironmentPostProcessor, Ordered { + + private static final String PROPERTY_KEY = "mybatis-plus.global-config.enable-sql-runner"; + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + if (!environment.containsProperty(PROPERTY_KEY)) { + Properties properties = new Properties(); + properties.setProperty(PROPERTY_KEY, "true"); + PropertiesPropertySource propertySource = new PropertiesPropertySource(PROPERTY_KEY, properties); + environment.getPropertySources().addLast(propertySource); + } + } + + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/JoinSegment.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/JoinSegment.java new file mode 100644 index 0000000000000000000000000000000000000000..46d5eb8ea6ce886da13dd1d2fdf4ea5ae0787877 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/JoinSegment.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class JoinSegment { + + private String joinTableName; + private String joinTableAlias; + private String sql; + + @Override + public String toString() { + return sql; + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/Metadata.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/Metadata.java new file mode 100644 index 0000000000000000000000000000000000000000..eec1966800a348581b5257a433345ce10df8c21e --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/Metadata.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Metadata { + private Class pojoClass; +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/SqlSegment.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/SqlSegment.java new file mode 100644 index 0000000000000000000000000000000000000000..395df5e5506b3c810fec604b45904f855e237ee9 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/entity/SqlSegment.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; +import java.util.Set; + +@Data +@AllArgsConstructor +public class SqlSegment { + + private String tableName; + private String tableAlias; + private String sql; + private List joinSegments; + private String sqlCriteria; + private boolean rootReachable; + private boolean dirtyQuery; + private Set joinTableNames; + + @Override + public String toString() { + return sql; + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/AppenderContext.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/AppenderContext.java new file mode 100644 index 0000000000000000000000000000000000000000..6ba33c2b3956f7411b9c60d6f00cdcb856b233b4 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/AppenderContext.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.impl; + +import com.baomidou.mybatisplus.core.conditions.interfaces.Compare; +import com.gitee.spring.boot.starter.dorive.api.CriterionAppender; +import com.gitee.dorive.core.api.constant.Operator; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class AppenderContext { + + public final static Map OPERATOR_CRITERION_APPENDER_MAP = new ConcurrentHashMap<>(); + + static { + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.EQ, (abstractWrapper, property, value) -> { + if (value instanceof Collection) { + abstractWrapper.in(property, (Collection) value); + } else { + abstractWrapper.eq(property, value); + } + }); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.NE, (abstractWrapper, property, value) -> { + if (value instanceof Collection) { + abstractWrapper.notIn(property, (Collection) value); + } else { + abstractWrapper.ne(property, value); + } + }); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.IN, (abstractWrapper, property, value) -> abstractWrapper.in(property, (Collection) value)); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.NOT_IN, (abstractWrapper, property, value) -> abstractWrapper.notIn(property, (Collection) value)); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.IS, (abstractWrapper, property, value) -> abstractWrapper.isNull(property)); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.IS_NOT, (abstractWrapper, property, value) -> abstractWrapper.isNotNull(property)); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.LIKE, Compare::like); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.NOT_LIKE, Compare::notLike); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.GT, Compare::gt); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.GE, Compare::ge); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.LT, Compare::lt); + OPERATOR_CRITERION_APPENDER_MAP.put(Operator.LE, Compare::le); + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/EntityIndexResult.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/EntityIndexResult.java new file mode 100644 index 0000000000000000000000000000000000000000..88ac1a7a82a1781ea7bfdcbd367abb87c3868acf --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/EntityIndexResult.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.impl; + +import com.gitee.spring.boot.starter.dorive.util.NumberUtils; +import com.gitee.dorive.core.api.EntityIndex; +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.executor.UnionExample; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class EntityIndexResult extends Result implements EntityIndex { + + private final Map> primaryKeyMapping; + private final Map primaryKeyEntityMap; + + public EntityIndexResult(UnionExample unionExample, List> resultMaps, List entities, PropertyProxy primaryKeyProxy) { + super(entities); + + int rootSize = unionExample.getExamples().size(); + int entitySize = entities.size(); + primaryKeyMapping = new HashMap<>(rootSize * 4 / 3 + 1); + primaryKeyEntityMap = new HashMap<>(entitySize * 4 / 3 + 1); + + int averageSize = resultMaps.size() / rootSize + 1; + for (Map resultMap : resultMaps) { + Long rootPrimaryKey = NumberUtils.longValue(resultMap.get("$id")); + List existPrimaryKeys = primaryKeyMapping.computeIfAbsent(rootPrimaryKey, key -> new ArrayList<>(averageSize)); + Long primaryKey = NumberUtils.longValue(resultMap.get("id")); + existPrimaryKeys.add(primaryKey); + } + + for (Object entity : entities) { + Long primaryKey = NumberUtils.longValue(primaryKeyProxy.getValue(entity)); + primaryKeyEntityMap.put(primaryKey, entity); + } + } + + @Override + public List selectList(Object rootEntity, Object primaryKey) { + Long rootPrimaryKey = NumberUtils.longValue(primaryKey); + List existPrimaryKeys = primaryKeyMapping.get(rootPrimaryKey); + if (existPrimaryKeys != null && !existPrimaryKeys.isEmpty()) { + List entities = new ArrayList<>(existPrimaryKeys.size()); + for (Long existPrimaryKey : existPrimaryKeys) { + Object entity = primaryKeyEntityMap.get(existPrimaryKey); + entities.add(entity); + } + return entities; + } + return Collections.emptyList(); + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/SQLExampleBuilder.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/SQLExampleBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..f0f7db5a5718e2d169d00f2617fc74f711531236 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/impl/SQLExampleBuilder.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.extension.toolkit.SqlRunner; +import com.gitee.spring.boot.starter.dorive.entity.JoinSegment; +import com.gitee.spring.boot.starter.dorive.entity.Metadata; +import com.gitee.spring.boot.starter.dorive.entity.SqlSegment; +import com.gitee.dorive.coating.api.ExampleBuilder; +import com.gitee.dorive.coating.entity.CoatingWrapper; +import com.gitee.dorive.coating.entity.RepositoryWrapper; +import com.gitee.dorive.coating.entity.MergedRepository; +import com.gitee.dorive.coating.entity.SpecificProperties; +import com.gitee.dorive.coating.impl.resolver.CoatingWrapperResolver; +import com.gitee.dorive.coating.repository.AbstractCoatingRepository; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.definition.BindingDefinition; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.OrderBy; +import com.gitee.dorive.core.entity.executor.Page; +import com.gitee.dorive.core.impl.binder.PropertyBinder; +import com.gitee.dorive.core.impl.resolver.BinderResolver; +import com.gitee.dorive.core.repository.ConfiguredRepository; + +import java.util.*; +import java.util.stream.Collectors; + +public class SQLExampleBuilder implements ExampleBuilder { + + private final AbstractCoatingRepository repository; + + public SQLExampleBuilder(AbstractCoatingRepository repository) { + this.repository = repository; + } + + @Override + public Example buildExample(BoundedContext boundedContext, Object coatingObject) { + CoatingWrapperResolver coatingWrapperResolver = repository.getCoatingWrapperResolver(); + Map, CoatingWrapper> coatingWrapperMap = coatingWrapperResolver.getCoatingWrapperMap(); + + CoatingWrapper coatingWrapper = coatingWrapperMap.get(coatingObject.getClass()); + Assert.notNull(coatingWrapper, "No coating wrapper exists!"); + + List repositoryWrappers = coatingWrapper.getRepositoryWrappers(); + SpecificProperties specificProperties = coatingWrapper.getSpecificProperties(); + OrderBy orderByInfo = specificProperties.getOrderBy(coatingObject); + Page pageInfo = specificProperties.getPage(coatingObject); + + Map sqlSegmentMap = new LinkedHashMap<>(repositoryWrappers.size() * 4 / 3 + 1); + SqlSegment rootSqlSegment = null; + char letter = 'a'; + + for (RepositoryWrapper repositoryWrapper : repositoryWrappers) { + MergedRepository mergedRepository = repositoryWrapper.getMergedRepository(); + String absoluteAccessPath = mergedRepository.getAbsoluteAccessPath(); + ConfiguredRepository definedRepository = mergedRepository.getDefinedRepository(); + ConfiguredRepository configuredRepository = mergedRepository.getConfiguredRepository(); + + TableInfo tableInfo = getTableInfo(configuredRepository); + String tableName = tableInfo.getTableName(); + + String tableAlias = String.valueOf(letter); + letter = (char) (letter + 1); + + List joinSegments = newJoinSegments(sqlSegmentMap, definedRepository.getBinderResolver(), tableName, tableAlias); + + Example example = repositoryWrapper.newExampleByCoating(boundedContext, coatingObject); + String sqlCriteria = null; + if (example.isDirtyQuery()) { + sqlCriteria = CollUtil.join(example.getCriteria(), " AND ", tableAlias + ".", null); + } + + if ("/".equals(absoluteAccessPath)) { + String sql = String.format("SELECT %s.id FROM %s %s ", tableAlias, tableName, tableAlias); + rootSqlSegment = new SqlSegment(tableName, tableAlias, sql, joinSegments, sqlCriteria, true, example.isDirtyQuery(), new HashSet<>(8)); + sqlSegmentMap.put(tableName, rootSqlSegment); + + } else { + String sql = String.format("LEFT JOIN %s %s ON ", tableName, tableAlias); + SqlSegment sqlSegment = new SqlSegment(tableName, tableAlias, sql, joinSegments, sqlCriteria, false, example.isDirtyQuery(), new HashSet<>(8)); + sqlSegmentMap.put(tableName, sqlSegment); + } + } + + Example example = new Example(); + example.setOrderBy(orderByInfo); + example.setPage(pageInfo); + + assert rootSqlSegment != null; + markReachableAndDirty(sqlSegmentMap, rootSqlSegment); + if (!rootSqlSegment.isDirtyQuery()) { + return example; + } + + String sql = buildSQL(sqlSegmentMap, example); + List> resultMaps = SqlRunner.db().selectList(sql); + List primaryKeys = CollUtil.map(resultMaps, map -> map.get("id"), true); + if (!primaryKeys.isEmpty()) { + example.eq("id", primaryKeys); + } else { + example.setEmptyQuery(true); + } + + return example; + } + + private TableInfo getTableInfo(ConfiguredRepository repository) { + Metadata metadata = (Metadata) repository.getMetadata(); + Class pojoClass = metadata.getPojoClass(); + return TableInfoHelper.getTableInfo(pojoClass); + } + + private List newJoinSegments(Map sqlSegmentMap, BinderResolver binderResolver, String tableName, String tableAlias) { + List propertyBinders = binderResolver.getPropertyBinders(); + List joinSegments = new ArrayList<>(propertyBinders.size()); + for (PropertyBinder propertyBinder : propertyBinders) { + TableInfo joinTableInfo = getTableInfo(propertyBinder.getBelongRepository()); + String joinTableName = joinTableInfo.getTableName(); + + SqlSegment sqlSegment = sqlSegmentMap.get(joinTableName); + if (sqlSegment != null) { + String joinTableAlias = sqlSegment.getTableAlias(); + Set joinTableNames = sqlSegment.getJoinTableNames(); + joinTableNames.add(tableName); + + BindingDefinition bindingDefinition = propertyBinder.getBindingDefinition(); + String alias = StrUtil.toUnderlineCase(bindingDefinition.getAlias()); + String bindAlias = StrUtil.toUnderlineCase(bindingDefinition.getBindAlias()); + + String sqlCriteria = tableAlias + "." + alias + " = " + joinTableAlias + "." + bindAlias; + JoinSegment joinSegment = new JoinSegment(joinTableName, joinTableAlias, sqlCriteria); + joinSegments.add(joinSegment); + } + } + return joinSegments; + } + + private void markReachableAndDirty(Map sqlSegmentMap, SqlSegment lastSqlSegment) { + Set joinTableNames = lastSqlSegment.getJoinTableNames(); + for (String joinTableName : joinTableNames) { + SqlSegment joinSqlSegment = sqlSegmentMap.get(joinTableName); + if (joinSqlSegment != null) { + joinSqlSegment.setRootReachable(true); + markReachableAndDirty(sqlSegmentMap, joinSqlSegment); + if (joinSqlSegment.isDirtyQuery()) { + lastSqlSegment.setDirtyQuery(true); + } + } + } + } + + private String buildSQL(Map sqlSegmentMap, Example example) { + StringBuilder sqlBuilder = new StringBuilder(); + List sqlCriteria = new ArrayList<>(sqlSegmentMap.size()); + + for (SqlSegment sqlSegment : sqlSegmentMap.values()) { + if (sqlSegment.isRootReachable() && sqlSegment.isDirtyQuery()) { + sqlBuilder.append(sqlSegment); + + List joinSegments = sqlSegment.getJoinSegments(); + joinSegments = joinSegments.stream().filter(joinSegment -> { + SqlSegment joinSqlSegment = sqlSegmentMap.get(joinSegment.getJoinTableName()); + return joinSqlSegment.isRootReachable() && joinSqlSegment.isDirtyQuery(); + }).collect(Collectors.toList()); + + if (!joinSegments.isEmpty()) { + sqlBuilder.append(StrUtil.join(" AND ", joinSegments)).append(" "); + } + + if (sqlSegment.getSqlCriteria() != null) { + sqlCriteria.add(sqlSegment.getSqlCriteria()); + } + } + } + + sqlBuilder.append("WHERE ").append(StrUtil.join(" AND ", sqlCriteria)); + + OrderBy orderBy = example.getOrderBy(); + if (orderBy != null) { + sqlBuilder.append(" ").append(orderBy); + } + + Page page = example.getPage(); + if (page != null) { + sqlBuilder.append(" ").append(page); + } + + return sqlBuilder.toString(); + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/repository/MybatisPlusExecutor.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/repository/MybatisPlusExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..3455c78356e4350f0b1beaca852ba3151b4f5505 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/repository/MybatisPlusExecutor.java @@ -0,0 +1,305 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.repository; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.gitee.spring.boot.starter.dorive.api.CriterionAppender; +import com.gitee.spring.boot.starter.dorive.entity.Metadata; +import com.gitee.spring.boot.starter.dorive.impl.EntityIndexResult; +import com.gitee.dorive.core.api.EntityFactory; +import com.gitee.dorive.core.api.MetadataHolder; +import com.gitee.dorive.core.api.PropertyProxy; +import com.gitee.dorive.core.api.constant.Order; +import com.gitee.dorive.core.entity.BoundedContext; +import com.gitee.dorive.core.entity.Command; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.definition.EntityDefinition; +import com.gitee.dorive.core.entity.executor.Criterion; +import com.gitee.dorive.core.entity.executor.Example; +import com.gitee.dorive.core.entity.executor.OrderBy; +import com.gitee.dorive.core.entity.executor.Result; +import com.gitee.dorive.core.entity.executor.UnionExample; +import com.gitee.dorive.core.entity.operation.Delete; +import com.gitee.dorive.core.entity.operation.Insert; +import com.gitee.dorive.core.entity.operation.Operation; +import com.gitee.dorive.core.entity.operation.Query; +import com.gitee.dorive.core.entity.operation.Update; +import com.gitee.dorive.core.impl.executor.AbstractExecutor; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static com.gitee.spring.boot.starter.dorive.impl.AppenderContext.OPERATOR_CRITERION_APPENDER_MAP; + +@Getter +@Setter +@ToString +public class MybatisPlusExecutor extends AbstractExecutor implements MetadataHolder { + + private EntityDefinition entityDefinition; + private BaseMapper baseMapper; + private Class pojoClass; + private EntityFactory entityFactory; + + public MybatisPlusExecutor(EntityElement entityElement, + EntityDefinition entityDefinition, + BaseMapper baseMapper, + Class pojoClass, + EntityFactory entityFactory) { + super(entityElement); + this.entityDefinition = entityDefinition; + this.baseMapper = baseMapper; + this.pojoClass = pojoClass; + this.entityFactory = entityFactory; + } + + @Override + public Object getMetadata() { + return new Metadata(pojoClass); + } + + @Override + public Result executeQuery(BoundedContext boundedContext, Query query) { + if (query.getPrimaryKey() != null) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", query.getPrimaryKey()); + List> resultMaps = baseMapper.selectMaps(queryWrapper); + List entities = reconstitute(boundedContext, resultMaps); + return new Result<>(entities); + + } else if (query.getExample() != null) { + Example example = query.getExample(); + if (query.withoutPage()) { + if (example instanceof UnionExample) { + UnionExample unionExample = (UnionExample) example; + QueryWrapper queryWrapper = buildQueryWrapper(unionExample); + List> resultMaps = baseMapper.selectMaps(queryWrapper); + int resultSize = resultMaps.size(); + Set existIds = new HashSet<>(resultSize * 4 / 3 + 1); + List entities = new ArrayList<>(resultSize); + for (Map resultMap : resultMaps) { + Object id = resultMap.get("id"); + if (existIds.add(id)) { + Object entity = entityFactory.reconstitute(boundedContext, resultMap); + entities.add(entity); + } + } + return new EntityIndexResult(unionExample, resultMaps, entities, entityElement.getPrimaryKeyProxy()); + + } else { + QueryWrapper queryWrapper = buildQueryWrapper(example); + List> resultMaps = baseMapper.selectMaps(queryWrapper); + List entities = reconstitute(boundedContext, resultMaps); + return new Result<>(entities); + } + + } else { + com.gitee.dorive.core.entity.executor.Page page = example.getPage(); + Page> dataPage = new Page<>(page.getCurrent(), page.getSize()); + QueryWrapper queryWrapper = buildQueryWrapper(example); + + dataPage = baseMapper.selectMapsPage(dataPage, queryWrapper); + page.setTotal(dataPage.getTotal()); + + List> resultMaps = dataPage.getRecords(); + List entities = reconstitute(boundedContext, resultMaps); + page.setRecords(entities); + + return new Result<>(page); + } + + } else { + throw new RuntimeException("Unsupported query method!"); + } + } + + private List reconstitute(BoundedContext boundedContext, List> resultMaps) { + List entities = new ArrayList<>(resultMaps.size()); + for (Map resultMap : resultMaps) { + Object entity = entityFactory.reconstitute(boundedContext, resultMap); + entities.add(entity); + } + return entities; + } + + private QueryWrapper buildQueryWrapper(Example example) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + + String[] selectColumns = example.getSelectColumns(); + if (selectColumns != null) { + String sqlSelect = queryWrapper.select(pojoClass, i -> true).getSqlSelect(); + sqlSelect = sqlSelect + StringPool.COMMA + queryWrapper.select(selectColumns).getSqlSelect(); + queryWrapper.select(sqlSelect); + } + + for (Criterion criterion : example.getCriteria()) { + CriterionAppender criterionAppender = OPERATOR_CRITERION_APPENDER_MAP.get(criterion.getOperator()); + String property = StrUtil.toUnderlineCase(criterion.getProperty()); + criterionAppender.appendCriterion(queryWrapper, property, criterion.getValue()); + } + + OrderBy orderBy = example.getOrderBy(); + if (orderBy != null) { + String order = orderBy.getOrder(); + if (Order.ASC.equals(order)) { + queryWrapper.orderByAsc(orderBy.getColumns()); + + } else if (Order.DESC.equals(order)) { + queryWrapper.orderByDesc(orderBy.getColumns()); + } + } + + return queryWrapper; + } + + private QueryWrapper buildQueryWrapper(UnionExample unionExample) { + List examples = unionExample.getExamples(); + Assert.notEmpty(examples, "The examples cannot be empty!"); + + Example example = examples.get(0); + QueryWrapper queryWrapper = buildQueryWrapper(example); + + StringBuilder lastSql = new StringBuilder(); + if (example.getPage() != null) { + lastSql.append(example.getPage()).append(" "); + } + + for (int index = 1; index < examples.size(); index++) { + Example nextExample = examples.get(index); + QueryWrapper nextQueryWrapper = buildQueryWrapper(nextExample); + + String sqlSelect = nextQueryWrapper.getSqlSelect(); + String tableName = TableInfoHelper.getTableInfo(pojoClass).getTableName(); + String criteria = nextExample.buildCriteria(); + + String sql = ""; + if (nextExample.getOrderBy() == null && nextExample.getPage() == null) { + sql = String.format("UNION ALL (SELECT %s FROM %s WHERE %s) ", sqlSelect, tableName, criteria); + + } else if (nextExample.getOrderBy() != null && nextExample.getPage() != null) { + sql = String.format("UNION ALL (SELECT %s FROM %s WHERE %s %s %s) ", sqlSelect, tableName, criteria, nextExample.getOrderBy(), nextExample.getPage()); + + } else if (nextExample.getOrderBy() != null) { + sql = String.format("UNION ALL (SELECT %s FROM %s WHERE %s %s) ", sqlSelect, tableName, criteria, nextExample.getOrderBy()); + + } else if (nextExample.getPage() != null) { + sql = String.format("UNION ALL (SELECT %s FROM %s WHERE %s %s) ", sqlSelect, tableName, criteria, nextExample.getPage()); + } + lastSql.append(sql); + } + + if (lastSql.length() > 0) { + queryWrapper.last(lastSql.toString()); + } + return queryWrapper; + } + + @Override + public int execute(BoundedContext boundedContext, Operation operation) { + Object entity = operation.getEntity(); + Object persistentObject = entity != null ? entityFactory.deconstruct(boundedContext, entity) : null; + + if (operation instanceof Insert) { + int count = baseMapper.insert(persistentObject); + Object primaryKey = BeanUtil.getFieldValue(persistentObject, "id"); + PropertyProxy primaryKeyProxy = entityElement.getPrimaryKeyProxy(); + primaryKeyProxy.setValue(entity, primaryKey); + return count; + + } else if (operation instanceof Update) { + Update update = (Update) operation; + Object primaryKey = update.getPrimaryKey(); + Example example = update.getExample(); + + String commandKey = entityDefinition.getCommandKey(); + if (StringUtils.isNotBlank(commandKey) && boundedContext.containsKey(commandKey)) { + Command command = (Command) boundedContext.get(commandKey); + Set nullableProperties = command.getNullableProperties(); + if (nullableProperties != null && !nullableProperties.isEmpty()) { + example = primaryKey != null ? new Example().eq("id", primaryKey) : example; + UpdateWrapper updateWrapper = buildUpdateWrapper(persistentObject, nullableProperties, example); + return baseMapper.update(null, updateWrapper); + } + } + + if (primaryKey != null) { + return baseMapper.updateById(persistentObject); + + } else if (example != null) { + return baseMapper.update(persistentObject, buildUpdateWrapper(example)); + } + + } else if (operation instanceof Delete) { + Delete delete = (Delete) operation; + Object primaryKey = delete.getPrimaryKey(); + Example example = delete.getExample(); + if (primaryKey != null) { + return baseMapper.deleteById((Serializable) primaryKey); + + } else if (example != null) { + return baseMapper.delete(buildUpdateWrapper(example)); + } + } + return 0; + } + + private UpdateWrapper buildUpdateWrapper(Example example) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + for (Criterion criterion : example.getCriteria()) { + CriterionAppender criterionAppender = OPERATOR_CRITERION_APPENDER_MAP.get(criterion.getOperator()); + String property = StrUtil.toUnderlineCase(criterion.getProperty()); + criterionAppender.appendCriterion(updateWrapper, property, criterion.getValue()); + } + return updateWrapper; + } + + private UpdateWrapper buildUpdateWrapper(Object persistentObject, Set nullableProperties, Example example) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + List fieldList = TableInfoHelper.getTableInfo(pojoClass).getFieldList(); + for (TableFieldInfo tableFieldInfo : fieldList) { + String property = tableFieldInfo.getProperty(); + Object value = BeanUtil.getFieldValue(persistentObject, property); + if (value != null || nullableProperties.contains(property)) { + updateWrapper.set(true, tableFieldInfo.getColumn(), value); + } + } + for (Criterion criterion : example.getCriteria()) { + CriterionAppender criterionAppender = OPERATOR_CRITERION_APPENDER_MAP.get(criterion.getOperator()); + String property = StrUtil.toUnderlineCase(criterion.getProperty()); + criterionAppender.appendCriterion(updateWrapper, property, criterion.getValue()); + } + return updateWrapper; + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/repository/MybatisPlusRepository.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/repository/MybatisPlusRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..8fe9c6d41dcd91cdd4d7a96a0e8fe759be949ab8 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/repository/MybatisPlusRepository.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.repository; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.gitee.spring.boot.starter.dorive.impl.SQLExampleBuilder; +import com.gitee.dorive.coating.repository.AbstractCoatingRepository; +import com.gitee.dorive.core.api.EntityFactory; +import com.gitee.dorive.core.api.Executor; +import com.gitee.dorive.core.entity.EntityElement; +import com.gitee.dorive.core.entity.definition.EntityDefinition; +import com.gitee.dorive.core.impl.DefaultEntityFactory; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +public class MybatisPlusRepository extends AbstractCoatingRepository { + + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + this.exampleBuilder = new SQLExampleBuilder(this); + } + + @Override + @SuppressWarnings("unchecked") + protected Executor newExecutor(EntityElement entityElement, EntityDefinition entityDefinition) { + Class mapperClass = entityDefinition.getMapper(); + Object mapper = null; + Class pojoClass = null; + if (mapperClass != Object.class) { + mapper = applicationContext.getBean(mapperClass); + Type[] genericInterfaces = mapperClass.getGenericInterfaces(); + if (genericInterfaces.length > 0) { + Type genericInterface = mapperClass.getGenericInterfaces()[0]; + if (genericInterface instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) genericInterface; + Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; + pojoClass = (Class) actualTypeArgument; + } + } + } + + Class factoryClass = entityDefinition.getFactory(); + EntityFactory entityFactory; + if (factoryClass == DefaultEntityFactory.class) { + entityFactory = new DefaultEntityFactory(); + } else { + entityFactory = (EntityFactory) applicationContext.getBean(factoryClass); + } + if (entityFactory instanceof DefaultEntityFactory) { + DefaultEntityFactory defaultEntityFactory = (DefaultEntityFactory) entityFactory; + defaultEntityFactory.setEntityElement(entityElement); + defaultEntityFactory.setPojoClass(pojoClass); + } + + return new MybatisPlusExecutor(entityElement, entityDefinition, (BaseMapper) mapper, (Class) pojoClass, entityFactory); + } + +} diff --git a/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/util/NumberUtils.java b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/util/NumberUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..6166b42bdd9f9db4ceba397ae56cdb95bc803f19 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/java/com/gitee/spring/boot/starter/dorive/util/NumberUtils.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitee.spring.boot.starter.dorive.util; + +public class NumberUtils { + + public static Long longValue(Object object) { + if (object instanceof Number) { + return ((Number) object).longValue(); + } + return null; + } + +} diff --git a/spring-boot-starter-dorive/src/main/resources/META-INF/spring.factories b/spring-boot-starter-dorive/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000000000000000000000000000000000..2253962315afb4423ef3d1b4015486690ae49163 --- /dev/null +++ b/spring-boot-starter-dorive/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.env.EnvironmentPostProcessor=com.gitee.spring.boot.starter.dorive.config.EnvironmentProcessor diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/Coating.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/Coating.java deleted file mode 100644 index b6f0dedfc11ab3fcb46cd4be8f4f714373401d9b..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/Coating.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.coating.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Coating { - - String name() default ""; - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/CoatingScan.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/CoatingScan.java deleted file mode 100644 index 96b174dc9d5296787caec9f154c612fb13326ed7..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/CoatingScan.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.coating.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface CoatingScan { - - String[] value() default {}; - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/IgnoreProperty.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/IgnoreProperty.java deleted file mode 100644 index 0a2565ae64cd7e394175fcdb5388a196ef7b2fd3..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/IgnoreProperty.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.spring.domain.coating.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface IgnoreProperty { -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/Property.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/Property.java deleted file mode 100644 index 44e161418284328e6373de273ba7b856e3f6c713..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/annotation/Property.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.spring.domain.coating.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Property { - - String location() default ""; - - String alias() default ""; - - String operator() default "="; - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CoatingAssembler.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CoatingAssembler.java deleted file mode 100644 index 5dc35ac229e6e711c7a562e6110c8ef92857217a..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CoatingAssembler.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.spring.domain.coating.api; - -public interface CoatingAssembler { - - void assemble(Object coatingObject, Object entity); - - void disassemble(Object coatingObject, Object entity); - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CoatingRepository.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CoatingRepository.java deleted file mode 100644 index e83bbe33e9b0d4e79439fee4c2554503d6d6e019..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CoatingRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.gitee.spring.domain.coating.api; - -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityExample; - -import java.util.List; - -public interface CoatingRepository { - - EntityExample buildExample(BoundedContext boundedContext, Object coatingObject); - - List selectByCoating(BoundedContext boundedContext, Object coatingObject); - - T selectPageByCoating(BoundedContext boundedContext, Object coatingObject, Object page); - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CustomAssembler.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CustomAssembler.java deleted file mode 100644 index feed3814866c9bfa44c154b5dceaef322f5f5565..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/api/CustomAssembler.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.spring.domain.coating.api; - -public interface CustomAssembler { - - void assembleBy(Object entity); - - void disassembleTo(Object entity); - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/ChainCriterion.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/ChainCriterion.java deleted file mode 100644 index 467869d225f12ebcd79577380cc9a020343c52ad..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/ChainCriterion.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.gitee.spring.domain.coating.entity; - -import com.gitee.spring.domain.core.entity.EntityExample; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class ChainCriterion { - private RepositoryLocation repositoryLocation; - private EntityExample entityExample; -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/CoatingDefinition.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/CoatingDefinition.java deleted file mode 100644 index eb915436df8b7986e92cc5f37f28e4b69dbbe894..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/CoatingDefinition.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.spring.domain.coating.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import org.springframework.core.annotation.AnnotationAttributes; - -import java.util.Map; - -@Data -@AllArgsConstructor -public class CoatingDefinition { - private Class entityClass; - private Class coatingClass; - private AnnotationAttributes attributes; - private String name; - private Map propertyDefinitionMap; -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/PropertyDefinition.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/PropertyDefinition.java deleted file mode 100644 index 3f2f95293325ecd3780d45c36b396ac52d1f1fee..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/PropertyDefinition.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.spring.domain.coating.entity; - -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import lombok.AllArgsConstructor; -import lombok.Data; -import org.springframework.core.annotation.AnnotationAttributes; - -import java.lang.reflect.Field; - -@Data -@AllArgsConstructor -public class PropertyDefinition { - private Field declaredField; - private Class fieldClass; - private boolean collection; - private Class genericFieldClass; - private String fieldName; - private AnnotationAttributes attributes; - private String locationAttribute; - private String aliasAttribute; - private String operatorAttribute; - private boolean boundLocation; - private EntityPropertyChain entityPropertyChain; -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/RepositoryDefinition.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/RepositoryDefinition.java deleted file mode 100644 index 256a11fc5072a166d882039c8d97fa32062725ad..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/RepositoryDefinition.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.gitee.spring.domain.coating.entity; - -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class RepositoryDefinition { - private String prefixAccessPath; - private String absoluteAccessPath; - private boolean delegateRoot; - private ConfiguredRepository definitionRepository; - private ConfiguredRepository configuredRepository; -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/RepositoryLocation.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/RepositoryLocation.java deleted file mode 100644 index 5708bc80f4033ef320fb77085df21987003c3dcf..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/entity/RepositoryLocation.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.coating.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.List; - -@Data -@AllArgsConstructor -public class RepositoryLocation { - private RepositoryDefinition repositoryDefinition; - private List collectedPropertyDefinitions; -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/impl/DefaultCoatingAssembler.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/impl/DefaultCoatingAssembler.java deleted file mode 100644 index d13808dbb9d3782854ee257a3a96d2580bfc644d..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/impl/DefaultCoatingAssembler.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.gitee.spring.domain.coating.impl; - -import cn.hutool.core.util.ReflectUtil; -import com.gitee.spring.domain.coating.api.CoatingAssembler; -import com.gitee.spring.domain.coating.entity.CoatingDefinition; -import com.gitee.spring.domain.coating.entity.PropertyDefinition; -import com.gitee.spring.domain.coating.entity.RepositoryLocation; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.List; - -@Data -@AllArgsConstructor -public class DefaultCoatingAssembler implements CoatingAssembler { - - private CoatingDefinition coatingDefinition; - private List availablePropertyDefinitions; - private List reversedRepositoryLocations; - - @Override - public void assemble(Object coatingObject, Object entity) { - for (PropertyDefinition propertyDefinition : availablePropertyDefinitions) { - EntityPropertyChain entityPropertyChain = propertyDefinition.getEntityPropertyChain(); - Object targetValue = entityPropertyChain.getValue(entity); - ReflectUtil.setFieldValue(coatingObject, propertyDefinition.getDeclaredField(), targetValue); - } - } - - @Override - public void disassemble(Object coatingObject, Object entity) { - for (PropertyDefinition propertyDefinition : availablePropertyDefinitions) { - EntityPropertyChain entityPropertyChain = propertyDefinition.getEntityPropertyChain(); - Object fieldValue = ReflectUtil.getFieldValue(coatingObject, propertyDefinition.getDeclaredField()); - entityPropertyChain.setValue(entity, fieldValue); - } - } - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractAwareRepository.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractAwareRepository.java deleted file mode 100644 index ea01c50839ff69ce1413fef6b32e20d54eeb4738..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractAwareRepository.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.gitee.spring.domain.coating.repository; - -import cn.hutool.core.util.StrUtil; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.coating.entity.RepositoryDefinition; -import com.gitee.spring.domain.core.repository.AbstractRepository; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import com.gitee.spring.domain.event.repository.AbstractEventRepository; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.*; - -@Data -@EqualsAndHashCode(callSuper = false) -public abstract class AbstractAwareRepository extends AbstractEventRepository { - - protected Map repositoryDefinitionMap = new LinkedHashMap<>(); - - @Override - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - RepositoryDefinition rootRepositoryDefinition = new RepositoryDefinition( - "", - "/", - false, - rootRepository, - rootRepository); - repositoryDefinitionMap.put("/", rootRepositoryDefinition); - resolveRepositoryDefinitionMap(new ArrayList<>(), this); - } - - protected void resolveRepositoryDefinitionMap(List multiAccessPath, AbstractAwareRepository abstractAwareRepository) { - String prefixAccessPath = StrUtil.join("", multiAccessPath); - - for (ConfiguredRepository configuredRepository : abstractAwareRepository.getSubRepositories()) { - EntityDefinition entityDefinition = configuredRepository.getEntityDefinition(); - String absoluteAccessPath = prefixAccessPath + entityDefinition.getAccessPath(); - - AbstractRepository abstractRepository = configuredRepository.getProxyRepository(); - if (abstractRepository instanceof AbstractAwareRepository) { - AbstractAwareRepository repository = (AbstractAwareRepository) abstractRepository; - - RepositoryDefinition repositoryDefinition = new RepositoryDefinition( - prefixAccessPath, - absoluteAccessPath, - true, - configuredRepository, - repository.getRootRepository()); - repositoryDefinitionMap.put(absoluteAccessPath, repositoryDefinition); - - List newMultiAccessPath = new ArrayList<>(multiAccessPath); - newMultiAccessPath.add(entityDefinition.getAccessPath()); - resolveRepositoryDefinitionMap(newMultiAccessPath, repository); - - } else { - RepositoryDefinition repositoryDefinition = new RepositoryDefinition( - prefixAccessPath, - absoluteAccessPath, - false, - configuredRepository, - configuredRepository); - repositoryDefinitionMap.put(absoluteAccessPath, repositoryDefinition); - } - } - } - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractChainRepository.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractChainRepository.java deleted file mode 100644 index a588b707d555d0b4b13b6ea533e4f235b9550476..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractChainRepository.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.gitee.spring.domain.coating.repository; - -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.ReflectUtil; -import com.gitee.spring.domain.coating.entity.ChainCriterion; -import com.gitee.spring.domain.coating.entity.PropertyDefinition; -import com.gitee.spring.domain.coating.entity.RepositoryDefinition; -import com.gitee.spring.domain.coating.entity.RepositoryLocation; -import com.gitee.spring.domain.coating.impl.DefaultCoatingAssembler; -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.api.PropertyConverter; -import com.gitee.spring.domain.core.entity.*; -import com.gitee.spring.domain.core.impl.binder.PropertyEntityBinder; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import lombok.extern.slf4j.Slf4j; - -import java.util.*; - -@Slf4j -public abstract class AbstractChainRepository extends AbstractCoatingRepository { - - @Override - public EntityExample buildExample(BoundedContext boundedContext, Object coatingObject) { - DefaultCoatingAssembler defaultCoatingAssembler = (DefaultCoatingAssembler) classCoatingAssemblerMap.get(coatingObject.getClass()); - Assert.notNull(defaultCoatingAssembler, "No coating assembler exists!"); - - Map criterionMap = new LinkedHashMap<>(); - for (RepositoryLocation repositoryLocation : defaultCoatingAssembler.getReversedRepositoryLocations()) { - ChainCriterion chainCriterion = new ChainCriterion(repositoryLocation, new EntityExample()); - appendCriterionToExample(chainCriterion, coatingObject); - - RepositoryDefinition repositoryDefinition = repositoryLocation.getRepositoryDefinition(); - String absoluteAccessPath = repositoryDefinition.getAbsoluteAccessPath(); - absoluteAccessPath = repositoryDefinition.isDelegateRoot() ? absoluteAccessPath + "/" : absoluteAccessPath; - criterionMap.put(absoluteAccessPath, chainCriterion); - } - - executeChainQuery(boundedContext, criterionMap); - - ChainCriterion chainCriterion = criterionMap.get("/"); - Assert.notNull(chainCriterion, "The criterion cannot be null!"); - return chainCriterion.getEntityExample(); - } - - protected void appendCriterionToExample(ChainCriterion chainCriterion, Object coatingObject) { - RepositoryLocation repositoryLocation = chainCriterion.getRepositoryLocation(); - EntityExample entityExample = chainCriterion.getEntityExample(); - for (PropertyDefinition propertyDefinition : repositoryLocation.getCollectedPropertyDefinitions()) { - String aliasAttribute = propertyDefinition.getAliasAttribute(); - String operatorAttribute = propertyDefinition.getOperatorAttribute(); - Object fieldValue = ReflectUtil.getFieldValue(coatingObject, propertyDefinition.getDeclaredField()); - if (fieldValue != null) { - EntityCriterion entityCriterion = new EntityCriterion(aliasAttribute, operatorAttribute, fieldValue); - entityExample.addCriterion(entityCriterion); - } - } - } - - protected void executeChainQuery(BoundedContext boundedContext, Map criterionMap) { - criterionMap.forEach((accessPath, chainCriterion) -> { - if ("/".equals(accessPath)) return; - - RepositoryLocation repositoryLocation = chainCriterion.getRepositoryLocation(); - EntityExample entityExample = chainCriterion.getEntityExample(); - - RepositoryDefinition repositoryDefinition = repositoryLocation.getRepositoryDefinition(); - String prefixAccessPath = repositoryDefinition.getPrefixAccessPath(); - ConfiguredRepository definitionRepository = repositoryDefinition.getDefinitionRepository(); - ConfiguredRepository configuredRepository = repositoryDefinition.getConfiguredRepository(); - - EntityDefinition entityDefinition = definitionRepository.getEntityDefinition(); - - for (PropertyEntityBinder propertyEntityBinder : definitionRepository.getBoundEntityBinders()) { - String absoluteAccessPath = prefixAccessPath + propertyEntityBinder.getBelongAccessPath(); - ChainCriterion targetChainCriterion = criterionMap.get(absoluteAccessPath); - if (targetChainCriterion != null) { - EntityExample targetEntityExample = targetChainCriterion.getEntityExample(); - if (targetEntityExample.isEmptyQuery()) { - entityExample.setEmptyQuery(true); - break; - } - } - } - - if (!entityExample.isEmptyQuery()) { - for (EntityBinder entityBinder : definitionRepository.getContextEntityBinders()) { - String columnName = entityBinder.getColumnName(); - Object queryParameter = entityBinder.getBoundValue(boundedContext, null); - if (queryParameter != null) { - entityExample.eq(columnName, queryParameter); - } - } - } - - if (entityExample.isAllQuery()) { - return; - } - - List entities = Collections.emptyList(); - if (!entityExample.isEmptyQuery() && entityExample.isDirtyQuery()) { - entityExample.setSelectColumns(entityDefinition.getBoundColumns()); - entities = configuredRepository.selectByExample(boundedContext, entityExample); - } - - for (PropertyEntityBinder propertyEntityBinder : definitionRepository.getBoundEntityBinders()) { - String absoluteAccessPath = prefixAccessPath + propertyEntityBinder.getBelongAccessPath(); - ChainCriterion targetChainCriterion = criterionMap.get(absoluteAccessPath); - if (targetChainCriterion != null) { - EntityExample targetEntityExample = targetChainCriterion.getEntityExample(); - if (entities.isEmpty()) { - targetEntityExample.setEmptyQuery(true); - continue; - } - - List fieldValues = collectFieldValues(boundedContext, entities, propertyEntityBinder); - if (fieldValues.isEmpty()) { - targetEntityExample.setEmptyQuery(true); - continue; - } - - BindingDefinition bindingDefinition = propertyEntityBinder.getBindingDefinition(); - String bindAliasAttribute = bindingDefinition.getBindAliasAttribute(); - Object fieldValue = fieldValues.size() == 1 ? fieldValues.get(0) : fieldValues; - targetEntityExample.eq(bindAliasAttribute, fieldValue); - } - } - }); - } - - protected List collectFieldValues(BoundedContext boundedContext, List entities, PropertyEntityBinder propertyEntityBinder) { - PropertyConverter propertyConverter = propertyEntityBinder.getPropertyConverter(); - List fieldValues = new ArrayList<>(); - for (Object entity : entities) { - Object fieldValue = propertyEntityBinder.getFieldValue(boundedContext, entity); - if (fieldValue != null) { - fieldValue = propertyConverter.reverseConvert(boundedContext, fieldValue); - fieldValues.add(fieldValue); - } - } - return fieldValues; - } - -} diff --git a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractCoatingRepository.java b/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractCoatingRepository.java deleted file mode 100644 index 5b3d51e05622b79ab48d442179df5ec59e407d03..0000000000000000000000000000000000000000 --- a/spring-domain-coating/src/main/java/com/gitee/spring/domain/coating/repository/AbstractCoatingRepository.java +++ /dev/null @@ -1,211 +0,0 @@ -package com.gitee.spring.domain.coating.repository; - -import cn.hutool.core.lang.Assert; -import com.gitee.spring.domain.coating.annotation.Coating; -import com.gitee.spring.domain.coating.annotation.CoatingScan; -import com.gitee.spring.domain.coating.annotation.IgnoreProperty; -import com.gitee.spring.domain.coating.annotation.Property; -import com.gitee.spring.domain.coating.api.CoatingAssembler; -import com.gitee.spring.domain.coating.api.CoatingRepository; -import com.gitee.spring.domain.coating.api.CustomAssembler; -import com.gitee.spring.domain.coating.entity.CoatingDefinition; -import com.gitee.spring.domain.coating.entity.PropertyDefinition; -import com.gitee.spring.domain.coating.entity.RepositoryDefinition; -import com.gitee.spring.domain.coating.entity.RepositoryLocation; -import com.gitee.spring.domain.coating.impl.DefaultCoatingAssembler; -import com.gitee.spring.domain.coating.utils.ResourceUtils; -import com.gitee.spring.domain.core.constants.Attribute; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.entity.EntityExample; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.apache.commons.lang3.StringUtils; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.util.ReflectionUtils; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -@Data -@EqualsAndHashCode(callSuper = false) -public abstract class AbstractCoatingRepository extends AbstractAwareRepository implements CoatingRepository { - - public static final Set COATING_NAMES = new LinkedHashSet<>(); - protected Map, CoatingAssembler> classCoatingAssemblerMap = new ConcurrentHashMap<>(); - - @Override - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - CoatingScan coatingScan = AnnotatedElementUtils.getMergedAnnotation(this.getClass(), CoatingScan.class); - if (coatingScan != null) { - resolveCoatingAssemblers(coatingScan.value()); - } - } - - protected void resolveCoatingAssemblers(String... basePackages) throws Exception { - for (String basePackage : basePackages) { - List> classes = ResourceUtils.resolveClasses(basePackage); - for (Class coatingClass : classes) { - Map allPropertyDefinitionMap = new LinkedHashMap<>(); - List availablePropertyDefinitions = new ArrayList<>(); - Map> locationPropertyDefinitionsMap = new LinkedHashMap<>(); - Map fieldPropertyDefinitionMap = new LinkedHashMap<>(); - - ReflectionUtils.doWithLocalFields(coatingClass, declaredField -> { - if (declaredField.isAnnotationPresent(IgnoreProperty.class)) return; - - Class fieldClass = declaredField.getType(); - boolean isCollection = false; - Class genericFieldClass = fieldClass; - String fieldName = declaredField.getName(); - - if (Collection.class.isAssignableFrom(fieldClass)) { - isCollection = true; - ParameterizedType parameterizedType = (ParameterizedType) declaredField.getGenericType(); - Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; - genericFieldClass = (Class) actualTypeArgument; - } - - AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(declaredField, Property.class); - String locationAttribute = null; - String aliasAttribute = null; - String operatorAttribute = "="; - boolean isBoundLocation = false; - - if (attributes != null) { - locationAttribute = attributes.getString(Attribute.LOCATION_ATTRIBUTE); - aliasAttribute = attributes.getString(Attribute.ALIAS_ATTRIBUTE); - operatorAttribute = attributes.getString(Attribute.OPERATOR_ATTRIBUTE); - isBoundLocation = locationAttribute.startsWith("/"); - } - if (StringUtils.isBlank(aliasAttribute)) { - aliasAttribute = fieldName; - } - - Map fieldEntityPropertyChainMap = entityPropertiesResolver.getFieldEntityPropertyChainMap(); - EntityPropertyChain entityPropertyChain = fieldEntityPropertyChainMap.get(fieldName); - - PropertyDefinition propertyDefinition = new PropertyDefinition( - declaredField, fieldClass, isCollection, genericFieldClass, fieldName, - attributes, locationAttribute, aliasAttribute, operatorAttribute, isBoundLocation, - entityPropertyChain); - - allPropertyDefinitionMap.put(fieldName, propertyDefinition); - - if (entityPropertyChain != null && fieldClass == entityPropertyChain.getEntityClass()) { - availablePropertyDefinitions.add(propertyDefinition); - } - - if (isBoundLocation) { - List propertyDefinitions = locationPropertyDefinitionsMap.computeIfAbsent(locationAttribute, key -> new ArrayList<>()); - propertyDefinitions.add(propertyDefinition); - } else { - fieldPropertyDefinitionMap.put(fieldName, propertyDefinition); - } - }); - - List reversedRepositoryLocations = collectRepositoryLocations(locationPropertyDefinitionsMap, fieldPropertyDefinitionMap); - Collections.reverse(reversedRepositoryLocations); - checkFieldNames(coatingClass, allPropertyDefinitionMap.keySet(), reversedRepositoryLocations); - - AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(coatingClass, Coating.class); - String name = null; - if (attributes != null) { - name = attributes.getString(Attribute.NAME_ATTRIBUTE); - } - if (StringUtils.isBlank(name)) { - name = coatingClass.getSimpleName(); - } - Assert.isTrue(!COATING_NAMES.contains(name), "The same coating name exists!"); - COATING_NAMES.add(name); - - CoatingDefinition coatingDefinition = new CoatingDefinition(entityClass, coatingClass, attributes, name, allPropertyDefinitionMap); - CoatingAssembler coatingAssembler = new DefaultCoatingAssembler(coatingDefinition, availablePropertyDefinitions, reversedRepositoryLocations); - classCoatingAssemblerMap.put(coatingClass, coatingAssembler); - } - } - } - - protected List collectRepositoryLocations(Map> locationPropertyDefinitionsMap, - Map fieldPropertyDefinitionMap) { - List repositoryLocations = new ArrayList<>(); - - for (RepositoryDefinition repositoryDefinition : repositoryDefinitionMap.values()) { - String absoluteAccessPath = repositoryDefinition.getAbsoluteAccessPath(); - ConfiguredRepository configuredRepository = repositoryDefinition.getConfiguredRepository(); - EntityDefinition entityDefinition = configuredRepository.getEntityDefinition(); - List propertyDefinitions = new ArrayList<>(); - - List locationPropertyDefinitions = locationPropertyDefinitionsMap.get(absoluteAccessPath); - if (locationPropertyDefinitions != null) { - propertyDefinitions.addAll(locationPropertyDefinitions); - } - - for (String fieldName : entityDefinition.getFieldNames()) { - PropertyDefinition propertyDefinition = fieldPropertyDefinitionMap.get(fieldName); - if (propertyDefinition != null) { - propertyDefinitions.add(propertyDefinition); - } - } - - if (!propertyDefinitions.isEmpty() || entityDefinition.isBoundEntity()) { - RepositoryLocation repositoryLocation = new RepositoryLocation(repositoryDefinition, propertyDefinitions); - repositoryLocations.add(repositoryLocation); - } - } - - return repositoryLocations; - } - - protected void checkFieldNames(Class coatingClass, Set fieldNames, List repositoryLocations) { - Set remainFieldNames = new LinkedHashSet<>(fieldNames); - for (RepositoryLocation repositoryLocation : repositoryLocations) { - for (PropertyDefinition propertyDefinition : repositoryLocation.getCollectedPropertyDefinitions()) { - remainFieldNames.remove(propertyDefinition.getFieldName()); - } - } - if (!remainFieldNames.isEmpty()) { - String errorMessage = String.format("The field does not exist in the aggregate root! entity: %s, coating: %s, fieldNames: %s", - entityClass, coatingClass, remainFieldNames); - throw new RuntimeException(errorMessage); - } - } - - @Override - public List selectByCoating(BoundedContext boundedContext, Object coatingObject) { - EntityExample entityExample = buildExample(boundedContext, coatingObject); - return selectByExample(boundedContext, entityExample); - } - - @Override - public T selectPageByCoating(BoundedContext boundedContext, Object coatingObject, Object page) { - EntityExample entityExample = buildExample(boundedContext, coatingObject); - return selectPageByExample(boundedContext, entityExample, page); - } - - public T assemble(T coating, E entity) { - CoatingAssembler coatingAssembler = classCoatingAssemblerMap.get(coating.getClass()); - Assert.notNull(coatingAssembler, "No coating assembler exists!"); - coatingAssembler.assemble(coating, entity); - if (coating instanceof CustomAssembler) { - ((CustomAssembler) coating).assembleBy(entity); - } - return coating; - } - - public void disassemble(Object coating, E entity) { - CoatingAssembler coatingAssembler = classCoatingAssemblerMap.get(coating.getClass()); - Assert.notNull(coatingAssembler, "No coating assembler exists!"); - coatingAssembler.disassemble(coating, entity); - if (coating instanceof CustomAssembler) { - ((CustomAssembler) coating).disassembleTo(entity); - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Binding.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Binding.java deleted file mode 100644 index 9431de30caf694cd5850c6e9cac19b9994d4947d..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Binding.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.gitee.spring.domain.core.annotation; - -import com.gitee.spring.domain.core.impl.DefaultPropertyConverter; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Repeatable(Bindings.class) -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.FIELD}) -public @interface Binding { - - String field(); - - String alias() default ""; - - String bind(); - - String bindExp() default ""; - - String bindAlias() default ""; - - String property() default ""; - - Class converter() default DefaultPropertyConverter.class; - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Bindings.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Bindings.java deleted file mode 100644 index 72a16753ee818bf36a37c80f414c1c3015bc8538..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Bindings.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.core.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.FIELD}) -public @interface Bindings { - - Binding[] value(); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Entity.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Entity.java deleted file mode 100644 index 0224abdc331c43d67179263f4a9a73a3c926de5a..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Entity.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.gitee.spring.domain.core.annotation; - -import com.gitee.spring.domain.core.impl.DefaultEntityAssembler; -import com.gitee.spring.domain.core.repository.DefaultRepository; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.FIELD}) -public @interface Entity { - - String id() default ""; - - String[] scene() default {}; - - Class mapper() default Object.class; - - boolean useEntityExample() default false; - - boolean mapAsExample() default false; - - String orderByAsc() default ""; - - String orderByDesc() default ""; - - int order() default 0; - - Class assembler() default DefaultEntityAssembler.class; - - Class repository() default DefaultRepository.class; - -} - diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Repository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Repository.java deleted file mode 100644 index 0206da1fa638f18db79464a4b4e32157fab03093..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/annotation/Repository.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.gitee.spring.domain.core.annotation; - -import org.springframework.core.annotation.AliasFor; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@org.springframework.stereotype.Repository -public @interface Repository { - - @AliasFor(annotation = org.springframework.stereotype.Repository.class) - String value() default ""; - - String name() default ""; - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/BaseRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/BaseRepository.java deleted file mode 100644 index a30239450bdedbda3ac57dc0699c96979b2da8f5..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/BaseRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import java.util.List; - -public interface BaseRepository extends IRepository { - - E selectByPrimaryKey(PK primaryKey); - - List selectByExample(Object example); - - T selectPageByExample(Object example, Object page); - - int insert(E entity); - - int updateSelective(E entity); - - int update(E entity); - - int insertOrUpdate(E entity); - - int delete(E entity); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityAssembler.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityAssembler.java deleted file mode 100644 index d340ba7e9b8f5d5bd89a944762425d4200a9d221..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityAssembler.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import com.gitee.spring.domain.core.entity.BoundedContext; - -public interface EntityAssembler { - - Object assemble(BoundedContext boundedContext, Object persistentObject); - - Object disassemble(BoundedContext boundedContext, Object entity); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityBinder.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityBinder.java deleted file mode 100644 index cfa7789bd3c3f34a3749f708be17ef84f8f515ae..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityBinder.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import com.gitee.spring.domain.core.entity.BindingDefinition; -import com.gitee.spring.domain.core.entity.BoundedContext; - -public interface EntityBinder { - - BindingDefinition getBindingDefinition(); - - String getColumnName(); - - Object getBoundValue(BoundedContext boundedContext, Object rootEntity); - - void setBoundValue(BoundedContext boundedContext, Object rootEntity, Object property); - - Object getFieldValue(BoundedContext boundedContext, Object entity); - - void setFieldValue(BoundedContext boundedContext, Object entity, Object property); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityIndex.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityIndex.java deleted file mode 100644 index 3254fda8da4dd7f41baeb8a089abb17d3900f478..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityIndex.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import java.util.List; - -public interface EntityIndex { - - List selectList(Object rootEntity, ForeignKey foreignKey); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityMapper.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityMapper.java deleted file mode 100644 index 5ab1ae3bf44914f37cb2a28c0da82283f1b38f0e..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityMapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityExample; - -import java.util.List; - -public interface EntityMapper { - - Object newPage(Integer pageNum, Integer pageSize); - - List getDataFromPage(Object dataPage); - - Object newPageOfEntities(Object dataPage, List entities); - - Object buildExample(BoundedContext boundedContext, EntityExample entityExample); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityProperty.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityProperty.java deleted file mode 100644 index 40d87faebbc9c9f5cfb2dbc1441b10fc7cabe9c2..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/EntityProperty.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.spring.domain.core.api; - -public interface EntityProperty { - - Object getValue(Object entity); - - void setValue(Object entity, Object property); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/ForeignKey.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/ForeignKey.java deleted file mode 100644 index 4d3d75df94495bc7e80145f64f491ab4de376927..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/ForeignKey.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.core.api; - -public interface ForeignKey { - - int size(); - - boolean isEmpty(); - - String getKey(int index); - - void mergeFieldValue(String fieldName, Object fieldValue); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/GenericRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/GenericRepository.java deleted file mode 100644 index 0fd75a3561adaeb82c2f7629e13b528dd839fe0e..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/GenericRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import com.gitee.spring.domain.core.entity.BoundedContext; - -import java.util.List; - -public interface GenericRepository extends BaseRepository { - - int insertList(BoundedContext boundedContext, List entities); - - int updateList(BoundedContext boundedContext, List entities); - - int insertOrUpdateList(BoundedContext boundedContext, List entities); - - int deleteList(BoundedContext boundedContext, List entities); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/IRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/IRepository.java deleted file mode 100644 index 89fd4cf219778f084aaf9e46a8cfa1cf36d9954e..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/IRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import com.gitee.spring.domain.core.entity.BoundedContext; - -import java.util.List; - -public interface IRepository { - - E selectByPrimaryKey(BoundedContext boundedContext, PK primaryKey); - - List selectByExample(BoundedContext boundedContext, Object example); - - T selectPageByExample(BoundedContext boundedContext, Object example, Object page); - - int insert(BoundedContext boundedContext, E entity); - - int updateSelective(BoundedContext boundedContext, E entity); - - int update(BoundedContext boundedContext, E entity); - - int updateByExample(BoundedContext boundedContext, Object entity, Object example); - - int insertOrUpdate(BoundedContext boundedContext, E entity); - - int delete(BoundedContext boundedContext, E entity); - - int deleteByPrimaryKey(BoundedContext boundedContext, PK primaryKey); - - int deleteByExample(BoundedContext boundedContext, Object example); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/PropertyConverter.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/PropertyConverter.java deleted file mode 100644 index 5560cdfadb31f62536447383cce9c65670bda8c7..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/api/PropertyConverter.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.spring.domain.core.api; - -import com.gitee.spring.domain.core.entity.BoundedContext; - -public interface PropertyConverter { - - Object convert(BoundedContext boundedContext, Object property); - - Object reverseConvert(BoundedContext boundedContext, Object property); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/config/DomainCoreConfiguration.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/config/DomainCoreConfiguration.java deleted file mode 100644 index d6ce59463cb9a63ef7f18e9cd98ee354a4f94c26..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/config/DomainCoreConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.gitee.spring.domain.core.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; - -@Order(-100) -@Configuration -public class DomainCoreConfiguration { - - @Bean - public RepositoryContext repositoryContext() { - return new RepositoryContext(); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/Attribute.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/Attribute.java deleted file mode 100644 index 61dd9e91ee3dd0ce2c37c31e894dbe962e003798..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/Attribute.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.gitee.spring.domain.core.constants; - -public interface Attribute { - String NAME_ATTRIBUTE = "name"; - - String ID_ATTRIBUTE = "id"; - String SCENE_ATTRIBUTE = "scene"; - String MAPPER_ATTRIBUTE = "mapper"; - String USE_ENTITY_EXAMPLE_ATTRIBUTE = "useEntityExample"; - String MAP_AS_EXAMPLE_ATTRIBUTE = "mapAsExample"; - String ORDER_BY_ASC_ATTRIBUTE = "orderByAsc"; - String ORDER_BY_DESC_ATTRIBUTE = "orderByDesc"; - String ORDER_ATTRIBUTE = "order"; - String ASSEMBLER_ATTRIBUTE = "assembler"; - String REPOSITORY_ATTRIBUTE = "repository"; - - String FIELD_ATTRIBUTE = "field"; - String ALIAS_ATTRIBUTE = "alias"; - String BIND_ATTRIBUTE = "bind"; - String BIND_EXP_ATTRIBUTE = "bindExp"; - String BIND_ALIAS_ATTRIBUTE = "bindAlias"; - String PROPERTY_ATTRIBUTE = "property"; - String CONVERTER_ATTRIBUTE = "converter"; - - String LOCATION_ATTRIBUTE = "location"; - String OPERATOR_ATTRIBUTE = "operator"; -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/EntityState.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/EntityState.java deleted file mode 100644 index 4c6fdb0b929ee266a79fac681904af906ef0ab13..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/EntityState.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.core.constants; - -public interface EntityState { - int NONE = 0x00000000; - int INSERT = 0x00000001; - int UPDATE_SELECTIVE = 0x00000002; - int UPDATE = 0x00000004; - int DELETE = 0x00000008; - int INSERT_OR_UPDATE = INSERT | UPDATE; - int UPDATE_SELECTIVE_OR_UPDATE_OR_DELETE = UPDATE_SELECTIVE | UPDATE | DELETE; - int FORCE_IGNORE = 0x00000010; - int FORCE_INSERT = 0x00000010 | INSERT; -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/Operator.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/Operator.java deleted file mode 100644 index 76cee7716c1be3dc998a0998a920cbf0d470bd4f..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/constants/Operator.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.gitee.spring.domain.core.constants; - -public interface Operator { - String EQ = "="; - String NE = "!="; - String IN = "in"; - String NOT_IN = "not in"; - String IS_NULL = "is null"; - String IS_NOT_NULL = "is not null"; - String LIKE = "like"; - String NOT_LIKE = "not like"; - String GT = ">"; - String GE = ">="; - String LT = "<"; - String LE = "<="; -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/BindingDefinition.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/BindingDefinition.java deleted file mode 100644 index b06ab32be7ff18f91772a647ef4f29b545e9d1cc..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/BindingDefinition.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.gitee.spring.domain.core.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import org.springframework.core.annotation.AnnotationAttributes; - -@Data -@AllArgsConstructor -public class BindingDefinition { - private AnnotationAttributes attributes; - private String fieldAttribute; - private String aliasAttribute; - private String bindAttribute; - private String bindExpAttribute; - private String bindAliasAttribute; - private String propertyAttribute; - private Class converterClass; -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/BoundedContext.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/BoundedContext.java deleted file mode 100644 index 928fc7cccf79abdb5382c27ea3b04a3cf4e20791..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/BoundedContext.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.spring.domain.core.entity; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -import java.util.LinkedHashMap; - -@Data -@NoArgsConstructor -@EqualsAndHashCode(callSuper = false) -public class BoundedContext extends LinkedHashMap { - - public BoundedContext(String... scenes) { - put(scenes); - } - - public void put(String... scenes) { - for (String scene : scenes) { - put(scene, true); - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityCriterion.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityCriterion.java deleted file mode 100644 index ead2b0bf47912f947bc9b138a5b4f41bdfbf518a..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityCriterion.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.gitee.spring.domain.core.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class EntityCriterion { - protected String fieldName; - protected String operator; - protected Object fieldValue; -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityDefinition.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityDefinition.java deleted file mode 100644 index bf1b24a4d1712224e7cebc84cc97aaa9f63ffbd4..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityDefinition.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.gitee.spring.domain.core.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import org.springframework.core.annotation.AnnotationAttributes; - -import java.lang.reflect.AnnotatedElement; -import java.util.Set; - -@Data -@AllArgsConstructor -public class EntityDefinition { - private boolean aggregateRoot; - private String accessPath; - private AnnotatedElement annotatedElement; - private Class entityClass; - private boolean collection; - private Class genericEntityClass; - private String fieldName; - private Set fieldNames; - private AnnotationAttributes attributes; - private String idAttribute; - private Set sceneAttribute; - private Object mapper; - private Class pojoClass; - private boolean sameType; - private Class mappedClass; - private boolean useEntityExample; - private boolean mapAsExample; - private String orderByAsc; - private String orderByDesc; - private String[] orderBy; - private String sort; - private int orderAttribute; - private String[] boundColumns; - private boolean boundEntity; -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityExample.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityExample.java deleted file mode 100644 index bb462221501764da29c996984e04a33026c41a97..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityExample.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.gitee.spring.domain.core.entity; - -import com.gitee.spring.domain.core.constants.Operator; -import com.gitee.spring.domain.core.utils.StringUtils; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.List; - -@Data -@NoArgsConstructor -public class EntityExample { - - protected boolean emptyQuery = false; - protected String[] selectColumns; - protected List entityCriteria = new ArrayList<>(); - protected String[] orderBy; - protected String sort; - - public boolean isDirtyQuery() { - return entityCriteria.size() > 0; - } - - public boolean isAllQuery() { - return !emptyQuery && !isDirtyQuery(); - } - - public void setSelectColumns(String... columns) { - selectColumns = StringUtils.toUnderlineCase(columns); - } - - public void addCriterion(EntityCriterion entityCriterion) { - entityCriteria.add(entityCriterion); - } - - public EntityExample eq(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.EQ, fieldValue)); - return this; - } - - public EntityExample ne(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.NE, fieldValue)); - return this; - } - - public EntityExample in(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.IN, fieldValue)); - return this; - } - - public EntityExample notIn(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.NOT_IN, fieldValue)); - return this; - } - - public EntityExample isNull(String fieldName) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.IS_NULL, null)); - return this; - } - - public EntityExample isNotNull(String fieldName) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.IS_NOT_NULL, null)); - return this; - } - - public EntityExample like(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.LIKE, fieldValue)); - return this; - } - - public EntityExample notLike(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.NOT_LIKE, fieldValue)); - return this; - } - - public EntityExample gt(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.GT, fieldValue)); - return this; - } - - public EntityExample ge(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.GE, fieldValue)); - return this; - } - - public EntityExample lt(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.LT, fieldValue)); - return this; - } - - public EntityExample le(String fieldName, Object fieldValue) { - entityCriteria.add(new EntityCriterion(fieldName, Operator.LE, fieldValue)); - return this; - } - - public void orderByAsc(String... columns) { - orderBy = StringUtils.toUnderlineCase(columns); - sort = "asc"; - } - - public void orderByDesc(String... columns) { - orderBy = StringUtils.toUnderlineCase(columns); - sort = "desc"; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityPropertyChain.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityPropertyChain.java deleted file mode 100644 index d0d193de3d276c2a2b1e76e0e870b87757c35cd7..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/entity/EntityPropertyChain.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.gitee.spring.domain.core.entity; - -import com.gitee.spring.domain.core.api.EntityProperty; -import com.gitee.spring.domain.core.impl.EntityPropertyFactory; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.ToString; - -import java.lang.reflect.Field; - -@Data -@AllArgsConstructor -@ToString(exclude = "lastEntityPropertyChain") -public class EntityPropertyChain implements EntityProperty { - - private EntityPropertyChain lastEntityPropertyChain; - private Class lastEntityClass; - private String accessPath; - private Field declaredField; - private boolean annotatedEntity; - private Class entityClass; - private boolean collection; - private Class genericEntityClass; - private String fieldName; - private EntityProperty entityProperty; - - public EntityPropertyChain(EntityPropertyChain lastEntityPropertyChain, - EntityPropertyChain entityPropertyChain) { - this.lastEntityPropertyChain = lastEntityPropertyChain; - this.lastEntityClass = entityPropertyChain.getLastEntityClass(); - this.accessPath = entityPropertyChain.getAccessPath(); - this.declaredField = entityPropertyChain.getDeclaredField(); - this.annotatedEntity = entityPropertyChain.isAnnotatedEntity(); - this.entityClass = entityPropertyChain.getEntityClass(); - this.collection = entityPropertyChain.isCollection(); - this.genericEntityClass = entityPropertyChain.getGenericEntityClass(); - this.fieldName = entityPropertyChain.getFieldName(); - this.entityProperty = entityPropertyChain.getEntityProperty(); - } - - public void initialize() { - if (entityProperty == null) { - entityProperty = EntityPropertyFactory.newEntityProperty(lastEntityClass, entityClass, fieldName); - if (lastEntityPropertyChain != null) { - lastEntityPropertyChain.initialize(); - } - } - } - - @Override - public Object getValue(Object entity) { - if (lastEntityPropertyChain != null) { - entity = lastEntityPropertyChain.getValue(entity); - } - return entity != null ? entityProperty.getValue(entity) : null; - } - - @Override - public void setValue(Object entity, Object property) { - if (lastEntityPropertyChain != null) { - entity = lastEntityPropertyChain.getValue(entity); - } - if (entity != null) { - entityProperty.setValue(entity, property); - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultEntityAssembler.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultEntityAssembler.java deleted file mode 100644 index 8901c60b8db6b1e4a93292b591a49acbc67cc842..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultEntityAssembler.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.gitee.spring.domain.core.impl; - -import cn.hutool.core.bean.BeanUtil; -import com.gitee.spring.domain.core.api.EntityAssembler; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class DefaultEntityAssembler implements EntityAssembler { - - protected EntityDefinition entityDefinition; - - @Override - public Object assemble(BoundedContext boundedContext, Object persistentObject) { - if (entityDefinition.isSameType()) { - return persistentObject; - } else { - return BeanUtil.copyProperties(persistentObject, entityDefinition.getGenericEntityClass()); - } - } - - @Override - public Object disassemble(BoundedContext boundedContext, Object entity) { - if (entityDefinition.isSameType()) { - return entity; - } else { - return BeanUtil.copyProperties(entity, entityDefinition.getMappedClass()); - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultEntityIndex.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultEntityIndex.java deleted file mode 100644 index aa5d4b233514ce5780448fc28cb7d3a59c18f395..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultEntityIndex.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.gitee.spring.domain.core.impl; - -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.api.EntityIndex; -import com.gitee.spring.domain.core.api.ForeignKey; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class DefaultEntityIndex implements EntityIndex { - - protected final Map entitiesMap = new ConcurrentHashMap<>(); - - @SuppressWarnings("unchecked") - public DefaultEntityIndex(BoundedContext boundedContext, List entities, ConfiguredRepository configuredRepository) { - for (Object entity : entities) { - StringBuilder builder = new StringBuilder(); - for (EntityBinder entityBinder : configuredRepository.getBoundEntityBinders()) { - String columnName = entityBinder.getColumnName(); - Object fieldValue = entityBinder.getFieldValue(boundedContext, entity); - builder.append(columnName).append(": ").append(fieldValue).append(", "); - } - if (builder.length() > 0) { - builder.delete(builder.length() - 2, builder.length()); - } - String foreignKey = builder.toString(); - Object existEntity = entitiesMap.get(foreignKey); - if (existEntity == null) { - entitiesMap.put(foreignKey, entity); - } else { - if (existEntity instanceof Collection) { - ((Collection) existEntity).add(entity); - } else { - List list = new ArrayList<>(); - list.add(existEntity); - list.add(entity); - entitiesMap.put(foreignKey, list); - } - } - } - } - - @Override - @SuppressWarnings("unchecked") - public List selectList(Object rootEntity, ForeignKey foreignKey) { - if (foreignKey.isEmpty()) { - return Collections.emptyList(); - - } else if (foreignKey.size() == 1) { - Object existEntity = entitiesMap.get(foreignKey.getKey(0)); - if (existEntity instanceof Collection) { - return (List) existEntity; - - } else if (existEntity != null) { - return Collections.singletonList(existEntity); - - } else { - return Collections.emptyList(); - } - } else { - List fieldValues = new ArrayList<>(); - for (int index = 0; index < foreignKey.size(); index++) { - String key = foreignKey.getKey(index); - Object existEntity = entitiesMap.get(key); - if (existEntity != null) { - if (existEntity instanceof Collection) { - fieldValues.addAll((Collection) existEntity); - } else { - fieldValues.add(existEntity); - } - } - } - return fieldValues; - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultPropertyConverter.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultPropertyConverter.java deleted file mode 100644 index 9b2dc6c09424c745059cb8f3f8a21520c9554e41..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/DefaultPropertyConverter.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.gitee.spring.domain.core.impl; - -import cn.hutool.core.bean.BeanUtil; -import com.gitee.spring.domain.core.api.PropertyConverter; -import com.gitee.spring.domain.core.entity.BindingDefinition; -import com.gitee.spring.domain.core.entity.BoundedContext; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class DefaultPropertyConverter implements PropertyConverter { - - protected BindingDefinition bindingDefinition; - - @Override - public Object convert(BoundedContext boundedContext, Object property) { - String propertyAttribute = bindingDefinition.getPropertyAttribute(); - if (StringUtils.isBlank(propertyAttribute)) { - return property; - } else { - if (property instanceof Collection) { - List fieldValues = new ArrayList<>(); - for (Object eachProperty : (Collection) property) { - Object fieldValue = BeanUtil.getFieldValue(eachProperty, propertyAttribute); - fieldValues.add(fieldValue); - } - return fieldValues; - } else { - return BeanUtil.getFieldValue(property, propertyAttribute); - } - } - } - - @Override - public Object reverseConvert(BoundedContext boundedContext, Object property) { - return property; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityPropertiesResolver.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityPropertiesResolver.java deleted file mode 100644 index 7af08e1389963f770d17b7b79e312ef7f5083a7e..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityPropertiesResolver.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.gitee.spring.domain.core.impl; - -import com.gitee.spring.domain.core.annotation.Entity; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import lombok.Data; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.util.ReflectionUtils; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.Map; - -@Data -public class EntityPropertiesResolver { - - private Map allEntityPropertyChainMap = new LinkedHashMap<>(); - private Map fieldEntityPropertyChainMap = new LinkedHashMap<>(); - - public void resolveEntityProperties(String lastAccessPath, Class entityClass) { - ReflectionUtils.doWithLocalFields(entityClass, declaredField -> { - Class fieldEntityClass = declaredField.getType(); - boolean isCollection = false; - Class fieldGenericEntityClass = fieldEntityClass; - String fieldName = declaredField.getName(); - - if (Collection.class.isAssignableFrom(fieldEntityClass)) { - isCollection = true; - ParameterizedType parameterizedType = (ParameterizedType) declaredField.getGenericType(); - Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; - fieldGenericEntityClass = (Class) actualTypeArgument; - } - - EntityPropertyChain lastEntityPropertyChain = allEntityPropertyChainMap.get(lastAccessPath); - String fieldAccessPath = lastAccessPath + "/" + fieldName; - boolean isAnnotatedEntity = AnnotatedElementUtils.isAnnotated(declaredField, Entity.class); - - EntityPropertyChain entityPropertyChain = new EntityPropertyChain( - lastEntityPropertyChain, - entityClass, - fieldAccessPath, - declaredField, - isAnnotatedEntity, - fieldEntityClass, - isCollection, - fieldGenericEntityClass, - fieldName, - null); - - if (isAnnotatedEntity) { - entityPropertyChain.initialize(); - } - - allEntityPropertyChainMap.put(fieldAccessPath, entityPropertyChain); - fieldEntityPropertyChainMap.putIfAbsent(fieldName, entityPropertyChain); - - if (!filterEntityClass(fieldEntityClass)) { - resolveEntityProperties(fieldAccessPath, fieldEntityClass); - } - }); - } - - private boolean filterEntityClass(Class entityClass) { - String className = entityClass.getName(); - return className.startsWith("java.lang.") || className.startsWith("java.util.") || entityClass.isEnum(); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityStateResolver.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityStateResolver.java deleted file mode 100644 index 6b0c1d03f152dfe9e135e13e5dd29f767e6ac400..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/EntityStateResolver.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.gitee.spring.domain.core.impl; - -import cn.hutool.core.bean.BeanUtil; -import com.gitee.spring.domain.core.constants.EntityState; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; - -public class EntityStateResolver { - - public int resolveContextEntityState(BoundedContext boundedContext, ConfiguredRepository configuredRepository) { - EntityDefinition entityDefinition = configuredRepository.getEntityDefinition(); - String idAttribute = entityDefinition.getIdAttribute(); - if (idAttribute != null) { - Object boundValue = boundedContext.get(idAttribute); - if ("#forceIgnore".equals(boundValue)) { - return EntityState.FORCE_IGNORE; - - } else if ("#forceInsert".equals(boundValue)) { - return EntityState.FORCE_INSERT; - } - } - return EntityState.NONE; - } - - public int resolveEntityState(int expectedEntityState, int contextEntityState, Object entity) { - if (contextEntityState == EntityState.FORCE_IGNORE) { - return EntityState.FORCE_IGNORE; - - } else if (contextEntityState == EntityState.FORCE_INSERT) { - return expectedEntityState & contextEntityState; - - } else if (expectedEntityState == EntityState.INSERT_OR_UPDATE) { - return EntityState.INSERT_OR_UPDATE; - - } else { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - contextEntityState = primaryKey == null ? EntityState.INSERT : EntityState.UPDATE_SELECTIVE_OR_UPDATE_OR_DELETE; - return expectedEntityState & contextEntityState; - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/AbstractEntityBuilder.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/AbstractEntityBuilder.java deleted file mode 100644 index c99ca2eb6ffc65d524a649e1c4ea996265b0411c..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/AbstractEntityBuilder.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.gitee.spring.domain.core.impl.binder; - -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.entity.BindingDefinition; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public abstract class AbstractEntityBuilder implements EntityBinder { - - protected BindingDefinition bindingDefinition; - protected EntityPropertyChain fieldEntityPropertyChain; - - @Override - public String getColumnName() { - return bindingDefinition.getAliasAttribute(); - } - - @Override - public Object getFieldValue(BoundedContext boundedContext, Object entity) { - return fieldEntityPropertyChain.getValue(entity); - } - - @Override - public void setFieldValue(BoundedContext boundedContext, Object entity, Object property) { - fieldEntityPropertyChain.setValue(entity, property); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/ContextEntityBinder.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/ContextEntityBinder.java deleted file mode 100644 index 33cb8914f9b013bd0f993e6541d3e16ca8957a1a..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/ContextEntityBinder.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.spring.domain.core.impl.binder; - -import com.gitee.spring.domain.core.entity.BindingDefinition; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; - -public class ContextEntityBinder extends AbstractEntityBuilder { - - public ContextEntityBinder(BindingDefinition bindingDefinition, EntityPropertyChain fieldEntityPropertyChain) { - super(bindingDefinition, fieldEntityPropertyChain); - } - - @Override - public Object getBoundValue(BoundedContext boundedContext, Object rootEntity) { - String bindAttribute = bindingDefinition.getBindAttribute(); - return boundedContext.get(bindAttribute); - } - - @Override - public void setBoundValue(BoundedContext boundedContext, Object rootEntity, Object property) { - // ignore - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/PropertyEntityBinder.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/PropertyEntityBinder.java deleted file mode 100644 index fa20f74c30b5721116c76772d6980dae966f1b80..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/binder/PropertyEntityBinder.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.gitee.spring.domain.core.impl.binder; - -import com.gitee.spring.domain.core.api.PropertyConverter; -import com.gitee.spring.domain.core.entity.BindingDefinition; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class PropertyEntityBinder extends AbstractEntityBuilder { - - protected String belongAccessPath; - protected ConfiguredRepository belongConfiguredRepository; - protected EntityPropertyChain boundEntityPropertyChain; - protected PropertyConverter propertyConverter; - - public PropertyEntityBinder(BindingDefinition bindingDefinition, - EntityPropertyChain fieldEntityPropertyChain, - String belongAccessPath, - ConfiguredRepository belongConfiguredRepository, - EntityPropertyChain boundEntityPropertyChain, - PropertyConverter propertyConverter) { - super(bindingDefinition, fieldEntityPropertyChain); - this.belongAccessPath = belongAccessPath; - this.belongConfiguredRepository = belongConfiguredRepository; - this.boundEntityPropertyChain = boundEntityPropertyChain; - this.propertyConverter = propertyConverter; - } - - public boolean isSameType() { - return boundEntityPropertyChain.getEntityClass() == fieldEntityPropertyChain.getEntityClass() - && boundEntityPropertyChain.getGenericEntityClass() == fieldEntityPropertyChain.getGenericEntityClass(); - } - - @Override - public Object getBoundValue(BoundedContext boundedContext, Object rootEntity) { - Object boundValue = boundEntityPropertyChain.getValue(rootEntity); - if (boundValue != null) { - boundValue = propertyConverter.convert(boundedContext, boundValue); - } - return boundValue; - } - - @Override - public void setBoundValue(BoundedContext boundedContext, Object rootEntity, Object property) { - boundEntityPropertyChain.setValue(rootEntity, property); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/key/MultipleForeignKey.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/key/MultipleForeignKey.java deleted file mode 100644 index a08abb0617828f01e3ecccf6dee869f105e9124a..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/key/MultipleForeignKey.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.gitee.spring.domain.core.impl.key; - -import com.gitee.spring.domain.core.api.ForeignKey; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@Data -@AllArgsConstructor -public class MultipleForeignKey implements ForeignKey { - - protected List keys; - - @Override - public int size() { - return keys.size(); - } - - @Override - public boolean isEmpty() { - return keys.isEmpty(); - } - - @Override - public String getKey(int index) { - return keys.get(index); - } - - @Override - public void mergeFieldValue(String fieldName, Object fieldValue) { - if (fieldValue instanceof Collection) { - Collection fieldValues = (Collection) fieldValue; - if (keys.isEmpty()) { - for (Object eachFieldValue : fieldValues) { - keys.add(fieldName + ": " + eachFieldValue); - } - } else { - List newKeys = new ArrayList<>(keys.size() * fieldValues.size()); - for (String existKey : keys) { - for (Object eachFieldValue : fieldValues) { - newKeys.add(existKey + ", " + fieldName + ": " + eachFieldValue); - } - } - keys = newKeys; - } - } else { - if (keys.isEmpty()) { - keys.add(fieldName + ": " + fieldValue); - } else { - for (int index = 0; index < keys.size(); index++) { - String existKey = keys.get(index); - keys.set(index, existKey + ", " + fieldName + ": " + fieldValue); - } - } - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/key/SingleForeignKey.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/key/SingleForeignKey.java deleted file mode 100644 index 6d56375468d58ab8fb17d26bed743843326ebba3..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/key/SingleForeignKey.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.gitee.spring.domain.core.impl.key; - -import com.gitee.spring.domain.core.api.ForeignKey; - -public class SingleForeignKey implements ForeignKey { - - protected String key; - - @Override - public int size() { - return key != null ? 1 : 0; - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public String getKey(int index) { - return index == 0 ? key : null; - } - - @Override - public void mergeFieldValue(String fieldName, Object fieldValue) { - key = fieldName + ": " + fieldValue; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/mapper/MapEntityMapper.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/mapper/MapEntityMapper.java deleted file mode 100644 index 754fa498c53cf68ed15132145763140a76a6eea3..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/mapper/MapEntityMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.gitee.spring.domain.core.impl.mapper; - -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityCriterion; -import com.gitee.spring.domain.core.entity.EntityExample; -import com.gitee.spring.domain.core.utils.DataUtils; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public class MapEntityMapper extends ProxyEntityMapper { - - public MapEntityMapper(EntityMapper entityMapper) { - super(entityMapper); - } - - @Override - public Object buildExample(BoundedContext boundedContext, EntityExample entityExample) { - Map mapExample = new LinkedHashMap<>(); - for (EntityCriterion entityCriterion : entityExample.getEntityCriteria()) { - String fieldName = entityCriterion.getFieldName(); - Object fieldValue = entityCriterion.getFieldValue(); - if (mapExample.containsKey(fieldName)) { - List fieldValues = DataUtils.intersection(mapExample.get(fieldName), fieldValue); - if (fieldValues.isEmpty()) { - entityExample.setEmptyQuery(true); - return null; - } - fieldValue = fieldValues.size() == 1 ? fieldValues.get(0) : fieldValues; - } - mapExample.put(fieldName, fieldValue); - } - return mapExample; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/mapper/ProxyEntityMapper.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/mapper/ProxyEntityMapper.java deleted file mode 100644 index 56288dd7bdef3799af7cc68e075b5c0829209b3c..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/impl/mapper/ProxyEntityMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.gitee.spring.domain.core.impl.mapper; - -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityExample; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.List; - -@Data -@AllArgsConstructor -public class ProxyEntityMapper implements EntityMapper { - - protected EntityMapper entityMapper; - - @Override - public Object newPage(Integer pageNum, Integer pageSize) { - return entityMapper.newPage(pageNum, pageSize); - } - - @Override - public List getDataFromPage(Object dataPage) { - return entityMapper.getDataFromPage(dataPage); - } - - @Override - public Object newPageOfEntities(Object dataPage, List entities) { - return entityMapper.newPageOfEntities(dataPage, entities); - } - - @Override - public Object buildExample(BoundedContext boundedContext, EntityExample entityExample) { - return entityMapper.buildExample(boundedContext, entityExample); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractBatchRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractBatchRepository.java deleted file mode 100644 index 98231f451eb213006cdb3667b01dcd74c6ec0ea6..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractBatchRepository.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.api.EntityIndex; -import com.gitee.spring.domain.core.api.EntityProperty; -import com.gitee.spring.domain.core.api.ForeignKey; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityExample; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import com.gitee.spring.domain.core.impl.binder.PropertyEntityBinder; -import com.gitee.spring.domain.core.impl.key.MultipleForeignKey; -import com.gitee.spring.domain.core.impl.key.SingleForeignKey; -import com.gitee.spring.domain.core.impl.DefaultEntityIndex; -import lombok.extern.slf4j.Slf4j; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -@Slf4j -public abstract class AbstractBatchRepository extends AbstractGenericRepository { - - @Override - protected void handleRootEntities(BoundedContext boundedContext, List rootEntities) { - if (rootEntities.size() == 1) { - super.handleRootEntity(boundedContext, rootEntities.get(0)); - - } else if (rootEntities.size() > 1) { - if (classDelegateRepositoryMap.size() == 1) { - executeQuery(boundedContext, rootEntities, this); - } else { - Map, List> repositoryEntitiesMap = adaptiveRepositoryEntities(rootEntities); - repositoryEntitiesMap.forEach((abstractDelegateRepository, eachRootEntities) -> - executeQuery(boundedContext, eachRootEntities, abstractDelegateRepository)); - } - } - } - - protected Map, List> adaptiveRepositoryEntities(List rootEntities) { - Map, List> repositoryEntitiesMap = new LinkedHashMap<>(); - for (Object rootEntity : rootEntities) { - AbstractDelegateRepository abstractDelegateRepository = adaptiveRepository(rootEntity); - List eachRootEntities = repositoryEntitiesMap.computeIfAbsent(abstractDelegateRepository, key -> new ArrayList<>()); - eachRootEntities.add(rootEntity); - } - return repositoryEntitiesMap; - } - - protected void executeQuery(BoundedContext boundedContext, List rootEntities, AbstractDelegateRepository abstractDelegateRepository) { - for (ConfiguredRepository configuredRepository : abstractDelegateRepository.getSubRepositories()) { - if (isMatchScenes(boundedContext, configuredRepository)) { - List foreignKeys = new ArrayList<>(rootEntities.size()); - EntityExample entityExample = newExampleByRootEntities(boundedContext, rootEntities, configuredRepository, foreignKeys); - if (!entityExample.isEmptyQuery() && entityExample.isDirtyQuery()) { - List entities = configuredRepository.selectByExample(boundedContext, entityExample); - EntityIndex entityIndex = buildEntityIndex(boundedContext, entities, configuredRepository); - assembleRootEntities(rootEntities, configuredRepository, foreignKeys, entityIndex); - } - } - } - } - - protected EntityExample newExampleByRootEntities(BoundedContext boundedContext, List rootEntities, - ConfiguredRepository configuredRepository, List foreignKeys) { - EntityExample entityExample = new EntityExample(); - List boundEntityBinders = configuredRepository.getBoundEntityBinders(); - for (int binderIndex = 0; binderIndex < boundEntityBinders.size(); binderIndex++) { - EntityBinder entityBinder = boundEntityBinders.get(binderIndex); - String columnName = entityBinder.getColumnName(); - List fieldValues = new ArrayList<>(); - for (int index = 0; index < rootEntities.size(); index++) { - Object rootEntity = rootEntities.get(index); - Object queryParameter = entityBinder.getBoundValue(boundedContext, rootEntity); - if (queryParameter instanceof Collection) { - fieldValues.addAll((Collection) queryParameter); - - } else if (queryParameter != null) { - fieldValues.add(queryParameter); - } - ForeignKey foreignKey; - if (binderIndex == 0) { - foreignKey = buildForeignKey(queryParameter, configuredRepository); - foreignKeys.add(foreignKey); - } else { - foreignKey = foreignKeys.get(index); - } - foreignKey.mergeFieldValue(columnName, queryParameter); - } - if (!fieldValues.isEmpty()) { - entityExample.eq(columnName, fieldValues); - } else { - entityExample.setEmptyQuery(true); - break; - } - } - if (!entityExample.isEmptyQuery() && entityExample.isDirtyQuery()) { - newCriterionByContext(boundedContext, null, configuredRepository, entityExample); - } - return entityExample; - } - - protected ForeignKey buildForeignKey(Object queryParameter, ConfiguredRepository configuredRepository) { - if (queryParameter instanceof Collection) { - return new MultipleForeignKey(new ArrayList<>(((Collection) queryParameter).size())); - - } else if (configuredRepository.getBoundEntityBinders().size() == 1) { - return new SingleForeignKey(); - } - return new MultipleForeignKey(new ArrayList<>(1)); - } - - protected EntityIndex buildEntityIndex(BoundedContext boundedContext, List entities, ConfiguredRepository configuredRepository) { - return new DefaultEntityIndex(boundedContext, entities, configuredRepository); - } - - protected void assembleRootEntities(List rootEntities, ConfiguredRepository configuredRepository, - List foreignKeys, EntityIndex entityIndex) { - for (int index = 0; index < rootEntities.size(); index++) { - Object rootEntity = rootEntities.get(index); - ForeignKey foreignKey = foreignKeys.get(index); - EntityPropertyChain entityPropertyChain = configuredRepository.getEntityPropertyChain(); - EntityPropertyChain lastEntityPropertyChain = entityPropertyChain.getLastEntityPropertyChain(); - Object lastEntity = lastEntityPropertyChain == null ? rootEntity : lastEntityPropertyChain.getValue(rootEntity); - if (lastEntity != null) { - List entities = entityIndex.selectList(rootEntity, foreignKey); - Object entity = convertManyToOneEntity(configuredRepository, entities); - if (entity != null) { - EntityProperty entityProperty = entityPropertyChain.getEntityProperty(); - entityProperty.setValue(lastEntity, entity); - } - } - } - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractContextRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractContextRepository.java deleted file mode 100644 index 0a9c5bd3633976a9dd8404172c1397fc5cdcea24..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractContextRepository.java +++ /dev/null @@ -1,411 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; -import com.gitee.spring.domain.core.annotation.Binding; -import com.gitee.spring.domain.core.annotation.Entity; -import com.gitee.spring.domain.core.annotation.Repository; -import com.gitee.spring.domain.core.api.EntityAssembler; -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.api.PropertyConverter; -import com.gitee.spring.domain.core.impl.binder.AbstractEntityBuilder; -import com.gitee.spring.domain.core.impl.binder.ContextEntityBinder; -import com.gitee.spring.domain.core.impl.binder.PropertyEntityBinder; -import com.gitee.spring.domain.core.constants.Attribute; -import com.gitee.spring.domain.core.entity.BindingDefinition; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import com.gitee.spring.domain.core.impl.DefaultEntityAssembler; -import com.gitee.spring.domain.core.impl.DefaultPropertyConverter; -import com.gitee.spring.domain.core.impl.EntityPropertiesResolver; -import com.gitee.spring.domain.core.impl.mapper.MapEntityMapper; -import com.gitee.spring.domain.core.utils.PathUtils; -import com.gitee.spring.domain.core.utils.ReflectUtils; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.annotation.AnnotationUtils; - -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -@Data -@EqualsAndHashCode(callSuper = false) -public abstract class AbstractContextRepository extends AbstractRepository implements ApplicationContextAware, InitializingBean { - - public static final Set REPOSITORY_NAMES = new LinkedHashSet<>(); - - protected Class entityClass; - protected Constructor entityCtor; - - protected AnnotationAttributes attributes; - protected String name; - - protected EntityPropertiesResolver entityPropertiesResolver = new EntityPropertiesResolver(); - - protected Map allConfiguredRepositoryMap = new LinkedHashMap<>(); - protected ConfiguredRepository rootRepository; - protected List subRepositories = new ArrayList<>(); - protected List orderedRepositories = new ArrayList<>(); - - protected ApplicationContext applicationContext; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @Override - public void afterPropertiesSet() throws Exception { - Type genericSuperclass = this.getClass().getGenericSuperclass(); - ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; - Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; - entityClass = (Class) actualTypeArgument; - entityCtor = ReflectUtils.getConstructor(entityClass, null); - - attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(this.getClass(), Repository.class); - if (attributes != null) { - name = attributes.getString(Attribute.NAME_ATTRIBUTE); - } - if (StringUtils.isBlank(name)) { - name = this.getClass().getSimpleName(); - } - Assert.isTrue(!REPOSITORY_NAMES.contains(name), "The same repository name exists!"); - REPOSITORY_NAMES.add(name); - - List> superClasses = ReflectUtils.getAllSuperClasses(entityClass, Object.class); - superClasses.forEach(superClass -> entityPropertiesResolver.resolveEntityProperties("", superClass)); - entityPropertiesResolver.resolveEntityProperties("", entityClass); - - resolveConfiguredRepository("/", entityClass); - Map allEntityPropertyChainMap = entityPropertiesResolver.getAllEntityPropertyChainMap(); - allEntityPropertyChainMap.forEach((accessPath, entityPropertyChain) -> { - if (entityPropertyChain.isAnnotatedEntity()) { - resolveConfiguredRepository(accessPath, entityPropertyChain.getDeclaredField()); - } - }); - postProcessAllRepositories(); - - orderedRepositories.sort(Comparator.comparingInt(configuredRepository -> configuredRepository.getEntityDefinition().getOrderAttribute())); - } - - protected void resolveConfiguredRepository(String accessPath, AnnotatedElement annotatedElement) { - AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(annotatedElement, Entity.class); - Set bindingAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations(annotatedElement, Binding.class); - if ("/".equals(accessPath)) { - ConfiguredRepository configuredRepository = newConfiguredRepository( - true, - "/", - annotatedElement, - null, - entityClass, - false, - entityClass, - null, - Objects.requireNonNull(attributes), - bindingAnnotations); - allConfiguredRepositoryMap.put(accessPath, configuredRepository); - rootRepository = configuredRepository; - orderedRepositories.add(configuredRepository); - - } else { - Map allEntityPropertyChainMap = entityPropertiesResolver.getAllEntityPropertyChainMap(); - EntityPropertyChain entityPropertyChain = allEntityPropertyChainMap.get(accessPath); - ConfiguredRepository configuredRepository = newConfiguredRepository( - false, - accessPath, - annotatedElement, - entityPropertyChain, - entityPropertyChain.getEntityClass(), - entityPropertyChain.isCollection(), - entityPropertyChain.getGenericEntityClass(), - entityPropertyChain.getFieldName(), - Objects.requireNonNull(attributes), - bindingAnnotations); - allConfiguredRepositoryMap.put(accessPath, configuredRepository); - subRepositories.add(configuredRepository); - orderedRepositories.add(configuredRepository); - } - } - - @SuppressWarnings("unchecked") - protected ConfiguredRepository newConfiguredRepository(boolean isAggregateRoot, - String accessPath, - AnnotatedElement annotatedElement, - EntityPropertyChain entityPropertyChain, - Class entityClass, - boolean isCollection, - Class genericEntityClass, - String fieldName, - AnnotationAttributes attributes, - Set bindingAnnotations) { - - String idAttribute = attributes.getString(Attribute.ID_ATTRIBUTE); - idAttribute = StringUtils.isNotBlank(idAttribute) ? idAttribute : null; - - String[] sceneAttributeStrs = attributes.getStringArray(Attribute.SCENE_ATTRIBUTE); - Set sceneAttribute = new LinkedHashSet<>(Arrays.asList(sceneAttributeStrs)); - - Class mapperClass = attributes.getClass(Attribute.MAPPER_ATTRIBUTE); - Object mapper = null; - Class pojoClass = null; - if (mapperClass != Object.class) { - mapper = applicationContext.getBean(mapperClass); - Type[] genericInterfaces = mapperClass.getGenericInterfaces(); - if (genericInterfaces.length > 0) { - Type genericInterface = mapperClass.getGenericInterfaces()[0]; - if (genericInterface instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) genericInterface; - Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; - pojoClass = (Class) actualTypeArgument; - } - } - } - boolean sameType = genericEntityClass == pojoClass; - Class mappedClass = pojoClass != null ? pojoClass : genericEntityClass; - - boolean useEntityExample = attributes.getBoolean(Attribute.USE_ENTITY_EXAMPLE_ATTRIBUTE); - boolean mapAsExample = attributes.getBoolean(Attribute.MAP_AS_EXAMPLE_ATTRIBUTE); - - String orderByAsc = attributes.getString(Attribute.ORDER_BY_ASC_ATTRIBUTE); - String orderByDesc = attributes.getString(Attribute.ORDER_BY_DESC_ATTRIBUTE); - String[] orderBy = null; - String sort = null; - if (StringUtils.isNotBlank(orderByAsc)) { - orderByAsc = StrUtil.toUnderlineCase(orderByAsc); - orderBy = StrUtil.splitTrim(orderByAsc, ",").toArray(new String[0]); - sort = "asc"; - } - if (StringUtils.isNotBlank(orderByDesc)) { - orderByAsc = StrUtil.toUnderlineCase(orderByAsc); - orderBy = StrUtil.splitTrim(orderByDesc, ",").toArray(new String[0]); - sort = "desc"; - } - - int orderAttribute = attributes.getNumber(Attribute.ORDER_ATTRIBUTE).intValue(); - Class assemblerClass = attributes.getClass(Attribute.ASSEMBLER_ATTRIBUTE); - Class repositoryClass = attributes.getClass(Attribute.REPOSITORY_ATTRIBUTE); - - Set boundColumns = new LinkedHashSet<>(); - - List allEntityBinders = new ArrayList<>(); - List boundEntityBinders = new ArrayList<>(); - List contextEntityBinders = new ArrayList<>(); - - for (Binding bindingAnnotation : bindingAnnotations) { - AnnotationAttributes bindingAttributes = AnnotationUtils.getAnnotationAttributes( - bindingAnnotation, false, false); - - String fieldAttribute = bindingAttributes.getString(Attribute.FIELD_ATTRIBUTE); - String aliasAttribute = bindingAttributes.getString(Attribute.ALIAS_ATTRIBUTE); - String bindAttribute = bindingAttributes.getString(Attribute.BIND_ATTRIBUTE); - String bindExpAttribute = bindingAttributes.getString(Attribute.BIND_EXP_ATTRIBUTE); - String bindAliasAttribute = bindingAttributes.getString(Attribute.BIND_ALIAS_ATTRIBUTE); - String propertyAttribute = bindingAttributes.getString(Attribute.PROPERTY_ATTRIBUTE); - Class converterClass = bindingAttributes.getClass(Attribute.CONVERTER_ATTRIBUTE); - - if (StringUtils.isBlank(aliasAttribute)) { - aliasAttribute = fieldAttribute; - } - - if (bindAttribute.startsWith(".")) { - bindAttribute = PathUtils.getAbsolutePath(accessPath, bindAttribute); - } - - if (StringUtils.isBlank(bindExpAttribute)) { - bindExpAttribute = bindAttribute; - } - - boolean isBindProperty = bindAttribute.startsWith("/"); - - if (isBindProperty && StringUtils.isBlank(bindAliasAttribute)) { - bindAliasAttribute = StringUtils.isBlank(propertyAttribute) ? PathUtils.getFieldName(bindAttribute) : propertyAttribute; - } - - if (isBindProperty) { - boundColumns.add(StrUtil.toUnderlineCase(aliasAttribute)); - } - - BindingDefinition bindingDefinition = new BindingDefinition( - bindingAttributes, fieldAttribute, aliasAttribute, - bindAttribute, bindExpAttribute, bindAliasAttribute, - propertyAttribute, converterClass); - - if (isBindProperty) { - String belongAccessPath = PathUtils.getBelongPath(allConfiguredRepositoryMap.keySet(), bindAttribute); - ConfiguredRepository belongConfiguredRepository = allConfiguredRepositoryMap.get(belongAccessPath); - Assert.notNull(belongConfiguredRepository, "The belong repository cannot be null!"); - EntityDefinition entityDefinition = belongConfiguredRepository.getEntityDefinition(); - entityDefinition.setBoundEntity(true); - - Map allEntityPropertyChainMap = entityPropertiesResolver.getAllEntityPropertyChainMap(); - EntityPropertyChain boundEntityPropertyChain = allEntityPropertyChainMap.get(bindAttribute); - Assert.notNull(boundEntityPropertyChain, "The bound entity property cannot be null!"); - boundEntityPropertyChain.initialize(); - - PropertyConverter propertyConverter; - if (converterClass == DefaultPropertyConverter.class) { - propertyConverter = new DefaultPropertyConverter(bindingDefinition); - - } else if (DefaultPropertyConverter.class.isAssignableFrom(converterClass)) { - DefaultPropertyConverter defaultPropertyConverter = (DefaultPropertyConverter) applicationContext.getBean(converterClass); - defaultPropertyConverter.setBindingDefinition(bindingDefinition); - propertyConverter = defaultPropertyConverter; - - } else { - propertyConverter = (PropertyConverter) applicationContext.getBean(converterClass); - } - - PropertyEntityBinder propertyEntityBinder = new PropertyEntityBinder( - bindingDefinition, null, - belongAccessPath, belongConfiguredRepository, - boundEntityPropertyChain, propertyConverter); - allEntityBinders.add(propertyEntityBinder); - boundEntityBinders.add(propertyEntityBinder); - - } else { - ContextEntityBinder contextEntityBinder = new ContextEntityBinder(bindingDefinition, null); - allEntityBinders.add(contextEntityBinder); - contextEntityBinders.add(contextEntityBinder); - } - } - - EntityDefinition entityDefinition = new EntityDefinition( - isAggregateRoot, accessPath, annotatedElement, - entityClass, isCollection, genericEntityClass, fieldName, ReflectUtils.getFieldNames(genericEntityClass), - attributes, idAttribute, sceneAttribute, mapper, pojoClass, sameType, mappedClass, - useEntityExample, mapAsExample, orderByAsc, orderByDesc, orderBy, sort, orderAttribute, - boundColumns.toArray(new String[0]), false); - - EntityMapper entityMapper = newEntityMapper(entityDefinition); - if (mapAsExample) { - entityMapper = new MapEntityMapper(entityMapper); - } - - EntityAssembler entityAssembler; - if (assemblerClass == DefaultEntityAssembler.class) { - entityAssembler = new DefaultEntityAssembler(entityDefinition); - - } else if (DefaultEntityAssembler.class.isAssignableFrom(assemblerClass)) { - DefaultEntityAssembler defaultEntityAssembler = (DefaultEntityAssembler) applicationContext.getBean(assemblerClass); - defaultEntityAssembler.setEntityDefinition(entityDefinition); - entityAssembler = defaultEntityAssembler; - - } else { - entityAssembler = (EntityAssembler) applicationContext.getBean(assemblerClass); - } - - Object repository; - if (repositoryClass == DefaultRepository.class) { - Assert.isTrue(mapper != Object.class, "The mapper cannot be object class!"); - repository = new DefaultRepository(entityDefinition, entityMapper, entityAssembler, newRepository(entityDefinition)); - - } else if (DefaultRepository.class.isAssignableFrom(repositoryClass)) { - Assert.isTrue(mapper != Object.class, "The mapper cannot be object class!"); - DefaultRepository defaultRepository = (DefaultRepository) applicationContext.getBean(repositoryClass); - defaultRepository.setEntityDefinition(entityDefinition); - defaultRepository.setEntityMapper(entityMapper); - defaultRepository.setEntityAssembler(entityAssembler); - defaultRepository.setProxyRepository(newRepository(entityDefinition)); - repository = defaultRepository; - - } else { - repository = applicationContext.getBean(repositoryClass); - } - - ConfiguredRepository configuredRepository = new ConfiguredRepository( - (AbstractRepository) repository, entityPropertyChain, entityDefinition, - allEntityBinders, boundEntityBinders, contextEntityBinders, new ArrayList<>(), null, - entityMapper, entityAssembler, new LinkedHashMap<>()); - - return postProcessRepository(configuredRepository); - } - - protected ConfiguredRepository postProcessRepository(ConfiguredRepository configuredRepository) { - return configuredRepository; - } - - protected void postProcessAllRepositories() { - Map allEntityPropertyChainMap = entityPropertiesResolver.getAllEntityPropertyChainMap(); - allEntityPropertyChainMap.forEach((accessPath, entityPropertyChain) -> { - String lastAccessPath = PathUtils.getLastAccessPath(accessPath); - String belongAccessPath = PathUtils.getBelongPath(allConfiguredRepositoryMap.keySet(), lastAccessPath); - ConfiguredRepository belongConfiguredRepository = allConfiguredRepositoryMap.get(belongAccessPath); - Assert.notNull(belongConfiguredRepository, "The belong repository cannot be null!"); - Map entityPropertyChainMap = belongConfiguredRepository.getEntityPropertyChainMap(); - EntityPropertyChain lastEntityPropertyChain = entityPropertyChainMap.get(lastAccessPath); - EntityPropertyChain newEntityPropertyChain = new EntityPropertyChain(lastEntityPropertyChain, entityPropertyChain); - entityPropertyChainMap.put(accessPath, newEntityPropertyChain); - }); - - allConfiguredRepositoryMap.forEach((accessPath, configuredRepository) -> { - EntityDefinition entityDefinition = configuredRepository.getEntityDefinition(); - Map entityPropertyChainMap = configuredRepository.getEntityPropertyChainMap(); - String prefixAccessPath = entityDefinition.isAggregateRoot() ? "/" : entityDefinition.getAccessPath() + "/"; - - if (entityPropertyChainMap.isEmpty() && entityDefinition.isCollection()) { - EntityPropertiesResolver entityPropertiesResolver = new EntityPropertiesResolver(); - entityPropertiesResolver.resolveEntityProperties("", entityDefinition.getGenericEntityClass()); - Map subAllEntityPropertyChainMap = entityPropertiesResolver.getAllEntityPropertyChainMap(); - entityPropertyChainMap.putAll(subAllEntityPropertyChainMap); - prefixAccessPath = "/"; - } - - List boundValueEntityBinders = configuredRepository.getBoundValueEntityBinders(); - for (EntityBinder entityBinder : configuredRepository.getAllEntityBinders()) { - BindingDefinition bindingDefinition = entityBinder.getBindingDefinition(); - String fieldAttribute = bindingDefinition.getFieldAttribute(); - - if (entityBinder instanceof AbstractEntityBuilder) { - String fieldAccessPath = prefixAccessPath + bindingDefinition.getFieldAttribute(); - EntityPropertyChain entityPropertyChain = entityPropertyChainMap.get(fieldAccessPath); - Assert.notNull(entityPropertyChain, "The field entity property cannot be null!"); - entityPropertyChain.initialize(); - ((AbstractEntityBuilder) entityBinder).setFieldEntityPropertyChain(entityPropertyChain); - } - - if (entityBinder instanceof PropertyEntityBinder) { - PropertyEntityBinder propertyEntityBinder = (PropertyEntityBinder) entityBinder; - boolean isBlankProperty = StringUtils.isBlank(bindingDefinition.getPropertyAttribute()); - boolean isDefaultConverter = bindingDefinition.getConverterClass() == DefaultPropertyConverter.class; - if (propertyEntityBinder.isSameType() && isBlankProperty && isDefaultConverter) { - if (!"id".equals(fieldAttribute)) { - boundValueEntityBinders.add(entityBinder); - } else { - if (entityDefinition.getOrderAttribute() == 0) { - entityDefinition.setOrderAttribute(-1); - } - configuredRepository.setBoundIdEntityBinder(propertyEntityBinder); - } - } - - } else if (entityBinder instanceof ContextEntityBinder) { - boundValueEntityBinders.add(entityBinder); - } - } - }); - } - - protected abstract EntityMapper newEntityMapper(EntityDefinition entityDefinition); - - protected abstract AbstractRepository newRepository(EntityDefinition entityDefinition); - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractDelegateRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractDelegateRepository.java deleted file mode 100644 index ea95d496254b41c62be14cdf9af6f43445f6e235..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractDelegateRepository.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.springframework.util.ReflectionUtils; - -import java.util.*; - -@Data -@EqualsAndHashCode(callSuper = false) -public abstract class AbstractDelegateRepository extends AbstractContextRepository { - - protected Map, AbstractDelegateRepository> classDelegateRepositoryMap = new LinkedHashMap<>(); - - @Override - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - resolveDelegateRepositoryMap(); - } - - protected void resolveDelegateRepositoryMap() { - classDelegateRepositoryMap.put(entityClass, this); - ReflectionUtils.doWithLocalFields(this.getClass(), declaredField -> { - Class fieldClass = declaredField.getType(); - if (AbstractDelegateRepository.class.isAssignableFrom(fieldClass)) { - Object beanInstance = applicationContext.getBean(fieldClass); - AbstractDelegateRepository abstractDelegateRepository = (AbstractDelegateRepository) beanInstance; - Class fieldEntityClass = abstractDelegateRepository.getEntityClass(); - if (entityClass.isAssignableFrom(fieldEntityClass)) { - classDelegateRepositoryMap.put(fieldEntityClass, abstractDelegateRepository); - } - } - }); - } - - protected AbstractDelegateRepository adaptiveRepository(Class entityClass) { - return classDelegateRepositoryMap.get(entityClass); - } - - protected AbstractDelegateRepository adaptiveRepository(Object rootEntity) { - return adaptiveRepository(rootEntity.getClass()); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractGenericRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractGenericRepository.java deleted file mode 100644 index 9eb38a9c33bc2ed285dcb011e093ae2075f43f28..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractGenericRepository.java +++ /dev/null @@ -1,288 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import cn.hutool.core.lang.Assert; -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.api.EntityProperty; -import com.gitee.spring.domain.core.api.GenericRepository; -import com.gitee.spring.domain.core.constants.EntityState; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.entity.EntityExample; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import com.gitee.spring.domain.core.impl.EntityStateResolver; -import com.gitee.spring.domain.core.utils.StringUtils; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -public abstract class AbstractGenericRepository extends AbstractDelegateRepository implements GenericRepository { - - protected EntityStateResolver entityStateResolver = new EntityStateResolver(); - - @Override - @SuppressWarnings("unchecked") - public E selectByPrimaryKey(BoundedContext boundedContext, PK primaryKey) { - Object rootEntity = rootRepository.selectByPrimaryKey(boundedContext, primaryKey); - handleRootEntity(boundedContext, rootEntity); - return (E) rootEntity; - } - - @Override - @SuppressWarnings("unchecked") - public List selectByExample(BoundedContext boundedContext, Object example) { - List rootEntities = rootRepository.selectByExample(boundedContext, example); - handleRootEntities(boundedContext, rootEntities); - return (List) rootEntities; - } - - @Override - public T selectPageByExample(BoundedContext boundedContext, Object example, Object page) { - T dataPage = rootRepository.selectPageByExample(boundedContext, example, page); - EntityMapper entityMapper = rootRepository.getEntityMapper(); - List rootEntities = entityMapper.getDataFromPage(dataPage); - handleRootEntities(boundedContext, rootEntities); - return dataPage; - } - - protected void handleRootEntities(BoundedContext boundedContext, List rootEntities) { - rootEntities.forEach(rootEntity -> handleRootEntity(boundedContext, rootEntity)); - } - - protected void handleRootEntity(BoundedContext boundedContext, Object rootEntity) { - if (rootEntity == null) return; - AbstractDelegateRepository abstractDelegateRepository = adaptiveRepository(rootEntity); - for (ConfiguredRepository configuredRepository : abstractDelegateRepository.getSubRepositories()) { - EntityPropertyChain entityPropertyChain = configuredRepository.getEntityPropertyChain(); - EntityPropertyChain lastEntityPropertyChain = entityPropertyChain.getLastEntityPropertyChain(); - Object lastEntity = lastEntityPropertyChain == null ? rootEntity : lastEntityPropertyChain.getValue(rootEntity); - if (lastEntity != null && isMatchScenes(boundedContext, configuredRepository)) { - EntityExample entityExample = newExampleByContext(boundedContext, rootEntity, configuredRepository); - if (!entityExample.isEmptyQuery() && entityExample.isDirtyQuery()) { - List entities = configuredRepository.selectByExample(boundedContext, entityExample); - Object entity = convertManyToOneEntity(configuredRepository, entities); - if (entity != null) { - EntityProperty entityProperty = entityPropertyChain.getEntityProperty(); - entityProperty.setValue(lastEntity, entity); - } - } - } - } - } - - protected boolean isMatchScenes(BoundedContext boundedContext, ConfiguredRepository configuredRepository) { - EntityDefinition entityDefinition = configuredRepository.getEntityDefinition(); - Set sceneAttribute = entityDefinition.getSceneAttribute(); - return isMatchScenes(boundedContext, sceneAttribute); - } - - protected boolean isMatchScenes(BoundedContext boundedContext, Set sceneAttribute) { - if (sceneAttribute.isEmpty()) { - return true; - } - for (String scene : sceneAttribute) { - if (boundedContext.containsKey(scene)) { - return true; - } - } - return false; - } - - protected EntityExample newExampleByContext(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository configuredRepository) { - EntityExample entityExample = new EntityExample(); - for (EntityBinder entityBinder : configuredRepository.getBoundEntityBinders()) { - String columnName = entityBinder.getColumnName(); - Object queryParameter = entityBinder.getBoundValue(boundedContext, rootEntity); - if (queryParameter instanceof Collection) { - queryParameter = !((Collection) queryParameter).isEmpty() ? queryParameter : null; - } - if (queryParameter != null) { - entityExample.eq(columnName, queryParameter); - } else { - entityExample.setEmptyQuery(true); - break; - } - } - if (!entityExample.isEmptyQuery() && entityExample.isDirtyQuery()) { - newCriterionByContext(boundedContext, rootEntity, configuredRepository, entityExample); - } - return entityExample; - } - - protected void newCriterionByContext(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository configuredRepository, EntityExample entityExample) { - for (EntityBinder entityBinder : configuredRepository.getContextEntityBinders()) { - String columnName = entityBinder.getColumnName(); - Object queryParameter = entityBinder.getBoundValue(boundedContext, rootEntity); - if (queryParameter != null) { - if (queryParameter instanceof String && StringUtils.isLike((String) queryParameter)) { - queryParameter = StringUtils.stripLike((String) queryParameter); - entityExample.like(columnName, queryParameter); - } else { - entityExample.eq(columnName, queryParameter); - } - } - } - } - - protected Object convertManyToOneEntity(ConfiguredRepository configuredRepository, List entities) { - EntityDefinition entityDefinition = configuredRepository.getEntityDefinition(); - if (entityDefinition.isCollection()) { - return entities; - } else if (!entities.isEmpty()) { - return entities.get(0); - } - return null; - } - - @Override - public int insert(BoundedContext boundedContext, E entity) { - return operateEntityByState(boundedContext, entity, EntityState.INSERT); - } - - @Override - public int updateSelective(BoundedContext boundedContext, E entity) { - return operateEntityByState(boundedContext, entity, EntityState.UPDATE_SELECTIVE); - } - - @Override - public int update(BoundedContext boundedContext, E entity) { - return operateEntityByState(boundedContext, entity, EntityState.UPDATE); - } - - @Override - public int updateByExample(BoundedContext boundedContext, Object entity, Object example) { - Assert.notNull(entity, "The entity cannot be null!"); - int totalCount = 0; - for (ConfiguredRepository configuredRepository : getOrderedRepositories()) { - if (isMatchScenes(boundedContext, configuredRepository)) { - int contextEntityState = entityStateResolver.resolveContextEntityState(boundedContext, configuredRepository); - if (contextEntityState == EntityState.NONE) { - totalCount += configuredRepository.updateByExample(boundedContext, entity, example); - } - } - } - return totalCount; - } - - @Override - public int insertOrUpdate(BoundedContext boundedContext, E entity) { - return operateEntityByState(boundedContext, entity, EntityState.INSERT_OR_UPDATE); - } - - @Override - public int delete(BoundedContext boundedContext, E entity) { - return operateEntityByState(boundedContext, entity, EntityState.DELETE); - } - - @Override - public int deleteByPrimaryKey(BoundedContext boundedContext, PK primaryKey) { - E entity = selectByPrimaryKey(boundedContext, primaryKey); - return delete(boundedContext, entity); - } - - @Override - public int deleteByExample(BoundedContext boundedContext, Object example) { - int totalCount = 0; - for (ConfiguredRepository configuredRepository : getOrderedRepositories()) { - if (isMatchScenes(boundedContext, configuredRepository)) { - int contextEntityState = entityStateResolver.resolveContextEntityState(boundedContext, configuredRepository); - if (contextEntityState == EntityState.NONE) { - totalCount += configuredRepository.deleteByExample(boundedContext, example); - } - } - } - return totalCount; - } - - protected int operateEntityByState(BoundedContext boundedContext, E entity, int expectedEntityState) { - Assert.notNull(entity, "The entity cannot be null!"); - int totalCount = 0; - AbstractDelegateRepository abstractDelegateRepository = adaptiveRepository(entity); - for (ConfiguredRepository configuredRepository : abstractDelegateRepository.getOrderedRepositories()) { - EntityPropertyChain entityPropertyChain = configuredRepository.getEntityPropertyChain(); - Object targetEntity = entityPropertyChain == null ? entity : entityPropertyChain.getValue(entity); - if (targetEntity != null && isMatchScenes(boundedContext, configuredRepository)) { - int contextEntityState = entityStateResolver.resolveContextEntityState(boundedContext, configuredRepository); - if (targetEntity instanceof Collection) { - for (Object eachEntity : (Collection) targetEntity) { - int entityState = entityStateResolver.resolveEntityState(expectedEntityState, contextEntityState, eachEntity); - totalCount += doOperateEntityByState(boundedContext, entity, configuredRepository, eachEntity, entityState); - } - } else { - int entityState = entityStateResolver.resolveEntityState(expectedEntityState, contextEntityState, targetEntity); - totalCount += doOperateEntityByState(boundedContext, entity, configuredRepository, targetEntity, entityState); - if (expectedEntityState == EntityState.INSERT_OR_UPDATE || expectedEntityState == EntityState.INSERT) { - setBoundIdForBoundEntity(boundedContext, entity, configuredRepository, targetEntity); - } - } - } - } - return totalCount; - } - - protected int doOperateEntityByState(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository configuredRepository, Object entity, - int entityState) { - if (entityState == EntityState.INSERT_OR_UPDATE) { - getBoundValueFromContext(boundedContext, rootEntity, configuredRepository, entity); - return configuredRepository.insertOrUpdate(boundedContext, entity); - - } else if (entityState == EntityState.INSERT) { - getBoundValueFromContext(boundedContext, rootEntity, configuredRepository, entity); - return configuredRepository.insert(boundedContext, entity); - - } else if (entityState == EntityState.UPDATE_SELECTIVE) { - return configuredRepository.updateSelective(boundedContext, entity); - - } else if (entityState == EntityState.UPDATE) { - return configuredRepository.update(boundedContext, entity); - - } else if (entityState == EntityState.DELETE) { - return configuredRepository.delete(boundedContext, entity); - } - return 0; - } - - protected void getBoundValueFromContext(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository configuredRepository, Object entity) { - for (EntityBinder entityBinder : configuredRepository.getBoundValueEntityBinders()) { - Object fieldValue = entityBinder.getFieldValue(boundedContext, entity); - if (fieldValue == null) { - Object boundValue = entityBinder.getBoundValue(boundedContext, rootEntity); - if (boundValue != null) { - entityBinder.setFieldValue(boundedContext, entity, boundValue); - } - } - } - } - - protected void setBoundIdForBoundEntity(BoundedContext boundedContext, Object rootEntity, ConfiguredRepository configuredRepository, Object entity) { - EntityBinder entityBinder = configuredRepository.getBoundIdEntityBinder(); - if (entityBinder != null) { - Object primaryKey = entityBinder.getFieldValue(boundedContext, entity); - if (primaryKey != null) { - entityBinder.setBoundValue(boundedContext, rootEntity, primaryKey); - } - } - } - - @Override - public int insertList(BoundedContext boundedContext, List entities) { - return entities.stream().mapToInt(entity -> insert(boundedContext, entity)).sum(); - } - - @Override - public int updateList(BoundedContext boundedContext, List entities) { - return entities.stream().mapToInt(entity -> update(boundedContext, entity)).sum(); - } - - @Override - public int insertOrUpdateList(BoundedContext boundedContext, List entities) { - return entities.stream().mapToInt(entity -> insertOrUpdate(boundedContext, entity)).sum(); - } - - @Override - public int deleteList(BoundedContext boundedContext, List entities) { - return entities.stream().mapToInt(entity -> delete(boundedContext, entity)).sum(); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractRepository.java deleted file mode 100644 index 032bf6ae34eb11e0421904dc20539e9851c12136..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/AbstractRepository.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import com.gitee.spring.domain.core.api.BaseRepository; -import com.gitee.spring.domain.core.entity.BoundedContext; - -import java.util.List; - -public abstract class AbstractRepository implements BaseRepository { - - @Override - public E selectByPrimaryKey(PK primaryKey) { - return selectByPrimaryKey(new BoundedContext(), primaryKey); - } - - @Override - public List selectByExample(Object example) { - return selectByExample(new BoundedContext(), example); - } - - @Override - public T selectPageByExample(Object example, Object page) { - return selectPageByExample(new BoundedContext(), example, page); - } - - @Override - public int insert(E entity) { - return insert(new BoundedContext(), entity); - } - - @Override - public int updateSelective(E entity) { - return updateSelective(new BoundedContext(), entity); - } - - @Override - public int update(E entity) { - return update(new BoundedContext(), entity); - } - - @Override - public int insertOrUpdate(E entity) { - return insertOrUpdate(new BoundedContext(), entity); - } - - @Override - public int delete(E entity) { - return delete(new BoundedContext(), entity); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/ConfiguredRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/ConfiguredRepository.java deleted file mode 100644 index b4d842bc55f32e4750c8e539e0c704ef798c2530..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/ConfiguredRepository.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import com.gitee.spring.domain.core.api.EntityAssembler; -import com.gitee.spring.domain.core.api.EntityBinder; -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.impl.binder.ContextEntityBinder; -import com.gitee.spring.domain.core.impl.binder.PropertyEntityBinder; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import com.gitee.spring.domain.core.entity.EntityExample; -import com.gitee.spring.domain.core.entity.EntityPropertyChain; -import lombok.Getter; -import lombok.Setter; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -@Getter -@Setter -public class ConfiguredRepository extends ProxyRepository { - - protected EntityPropertyChain entityPropertyChain; - protected EntityDefinition entityDefinition; - protected List allEntityBinders; - protected List boundEntityBinders; - protected List contextEntityBinders; - protected List boundValueEntityBinders; - protected PropertyEntityBinder boundIdEntityBinder; - protected EntityMapper entityMapper; - protected EntityAssembler entityAssembler; - protected Map entityPropertyChainMap; - - public ConfiguredRepository(AbstractRepository repository, - EntityPropertyChain entityPropertyChain, - EntityDefinition entityDefinition, - List allEntityBinders, - List boundEntityBinders, - List contextEntityBinders, - List boundValueEntityBinders, - PropertyEntityBinder boundIdEntityBinder, - EntityMapper entityMapper, - EntityAssembler entityAssembler, - Map entityPropertyChainMap) { - super(repository); - this.entityPropertyChain = entityPropertyChain; - this.entityDefinition = entityDefinition; - this.allEntityBinders = allEntityBinders; - this.boundEntityBinders = boundEntityBinders; - this.contextEntityBinders = contextEntityBinders; - this.boundValueEntityBinders = boundValueEntityBinders; - this.boundIdEntityBinder = boundIdEntityBinder; - this.entityMapper = entityMapper; - this.entityAssembler = entityAssembler; - this.entityPropertyChainMap = entityPropertyChainMap; - } - - public ConfiguredRepository(ConfiguredRepository configuredRepository) { - super(configuredRepository); - this.entityPropertyChain = configuredRepository.getEntityPropertyChain(); - this.entityDefinition = configuredRepository.getEntityDefinition(); - this.allEntityBinders = configuredRepository.getAllEntityBinders(); - this.boundEntityBinders = configuredRepository.getBoundEntityBinders(); - this.contextEntityBinders = configuredRepository.getContextEntityBinders(); - this.boundValueEntityBinders = configuredRepository.getBoundValueEntityBinders(); - this.boundIdEntityBinder = configuredRepository.getBoundIdEntityBinder(); - this.entityMapper = configuredRepository.getEntityMapper(); - this.entityAssembler = configuredRepository.getEntityAssembler(); - this.entityPropertyChainMap = configuredRepository.getEntityPropertyChainMap(); - } - - @Override - public AbstractRepository getProxyRepository() { - AbstractRepository abstractRepository = super.getProxyRepository(); - if (abstractRepository instanceof ConfiguredRepository) { - return ((ConfiguredRepository) abstractRepository).getProxyRepository(); - } - return abstractRepository; - } - - private Object buildExample(BoundedContext boundedContext, Object example) { - if (example instanceof EntityExample) { - EntityExample entityExample = (EntityExample) example; - if (entityExample.isEmptyQuery()) { - return null; - } else if (!entityDefinition.isUseEntityExample()) { - return entityMapper.buildExample(boundedContext, entityExample); - } - } - return example; - } - - @Override - public List selectByExample(BoundedContext boundedContext, Object example) { - example = buildExample(boundedContext, example); - return example != null ? super.selectByExample(boundedContext, example) : Collections.emptyList(); - } - - @Override - @SuppressWarnings("unchecked") - public T selectPageByExample(BoundedContext boundedContext, Object example, Object page) { - example = buildExample(boundedContext, example); - if (example == null) { - return (T) entityMapper.newPageOfEntities(page, Collections.emptyList()); - } else { - return super.selectPageByExample(boundedContext, example, page); - } - } - - @Override - public int updateByExample(BoundedContext boundedContext, Object entity, Object example) { - example = buildExample(new BoundedContext(), example); - return example != null ? super.updateByExample(boundedContext, entity, example) : 0; - } - - @Override - public int deleteByExample(BoundedContext boundedContext, Object example) { - example = buildExample(new BoundedContext(), example); - return example != null ? super.deleteByExample(boundedContext, example) : 0; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/DefaultRepository.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/DefaultRepository.java deleted file mode 100644 index 5cff399732b4207d9420d0d960e11466672253ec..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/repository/DefaultRepository.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.gitee.spring.domain.core.repository; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.lang.Assert; -import com.gitee.spring.domain.core.api.EntityAssembler; -import com.gitee.spring.domain.core.api.EntityMapper; -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.entity.EntityDefinition; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -@Data -@NoArgsConstructor -@EqualsAndHashCode(callSuper = false) -public class DefaultRepository extends ProxyRepository { - - protected EntityDefinition entityDefinition; - protected EntityMapper entityMapper; - protected EntityAssembler entityAssembler; - - public DefaultRepository(EntityDefinition entityDefinition, - EntityMapper entityMapper, - EntityAssembler entityAssembler, - AbstractRepository repository) { - super(repository); - this.entityDefinition = entityDefinition; - this.entityMapper = entityMapper; - this.entityAssembler = entityAssembler; - } - - @Override - public Object selectByPrimaryKey(BoundedContext boundedContext, Object primaryKey) { - Object persistentObject = super.selectByPrimaryKey(boundedContext, primaryKey); - if (persistentObject != null) { - return entityAssembler.assemble(boundedContext, persistentObject); - } - return null; - } - - @Override - public List selectByExample(BoundedContext boundedContext, Object example) { - List persistentObjects = super.selectByExample(boundedContext, example); - if (persistentObjects != null && !persistentObjects.isEmpty()) { - return newEntities(boundedContext, persistentObjects); - } - return Collections.emptyList(); - } - - protected List newEntities(BoundedContext boundedContext, List persistentObjects) { - List entities = new ArrayList<>(); - for (Object persistentObject : persistentObjects) { - Object entity = entityAssembler.assemble(boundedContext, persistentObject); - entities.add(entity); - } - return entities; - } - - @Override - @SuppressWarnings("unchecked") - public T selectPageByExample(BoundedContext boundedContext, Object example, Object page) { - Object dataPage = super.selectPageByExample(boundedContext, example, page); - List persistentObjects = entityMapper.getDataFromPage(dataPage); - if (persistentObjects != null && !persistentObjects.isEmpty()) { - List entities = newEntities(boundedContext, persistentObjects); - return (T) entityMapper.newPageOfEntities(dataPage, entities); - } - return (T) dataPage; - } - - @Override - public int insert(BoundedContext boundedContext, Object entity) { - Object persistentObject = entityAssembler.disassemble(boundedContext, entity); - if (persistentObject != null) { - int count = super.insert(boundedContext, persistentObject); - copyPrimaryKey(entity, persistentObject); - return count; - } - return 0; - } - - protected void copyPrimaryKey(Object entity, Object persistentObject) { - Object primaryKey = BeanUtil.getFieldValue(persistentObject, "id"); - BeanUtil.setFieldValue(entity, "id", primaryKey); - } - - @Override - public int updateSelective(BoundedContext boundedContext, Object entity) { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - if (primaryKey != null) { - Object persistentObject = entityAssembler.disassemble(boundedContext, entity); - if (persistentObject != null) { - return super.updateSelective(boundedContext, persistentObject); - } - } - return 0; - } - - @Override - public int update(BoundedContext boundedContext, Object entity) { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - if (primaryKey != null) { - Object persistentObject = entityAssembler.disassemble(boundedContext, entity); - if (persistentObject != null) { - return super.update(boundedContext, persistentObject); - } - } - return 0; - } - - @Override - public int updateByExample(BoundedContext boundedContext, Object entity, Object example) { - Assert.isTrue(!(entity instanceof Collection), "The entity cannot be a collection!"); - if (entity.getClass() != entityDefinition.getGenericEntityClass()) { - entity = BeanUtil.copyProperties(entity, entityDefinition.getGenericEntityClass()); - } - Object persistentObject = entityAssembler.disassemble(boundedContext, entity); - if (persistentObject != null) { - return super.updateByExample(boundedContext, persistentObject, example); - } - return 0; - } - - @Override - public int insertOrUpdate(BoundedContext boundedContext, Object entity) { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - if (primaryKey == null) { - return insert(boundedContext, entity); - } else { - return update(boundedContext, entity); - } - } - - @Override - public int delete(BoundedContext boundedContext, Object entity) { - Object primaryKey = BeanUtil.getFieldValue(entity, "id"); - if (primaryKey != null) { - return super.deleteByPrimaryKey(boundedContext, primaryKey); - } - return 0; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/DataUtils.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/DataUtils.java deleted file mode 100644 index 71155160100ac0d651f1c3d991d7ca17f21a7c82..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/DataUtils.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.gitee.spring.domain.core.utils; - -import cn.hutool.core.collection.CollUtil; - -import java.util.*; - -public class DataUtils { - - @SuppressWarnings("unchecked") - public static List intersection(Object value1, Object value2) { - Collection collection1 = value1 instanceof Collection ? (Collection) value1 : Collections.singletonList(value1); - Collection collection2 = value2 instanceof Collection ? (Collection) value2 : Collections.singletonList(value2); - return (List) CollUtil.intersection(collection1, collection2); - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/ReflectUtils.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/ReflectUtils.java deleted file mode 100644 index 66abc28d9761d05cc18cf86f5f9a5c4ebaa38230..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/ReflectUtils.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.gitee.spring.domain.core.utils; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -public class ReflectUtils { - - public static Constructor getConstructor(Class type, Class[] parameterTypes) { - return org.springframework.cglib.core.ReflectUtils.getConstructor(type, parameterTypes); - } - - public static Object newInstance(Class type) { - return org.springframework.cglib.core.ReflectUtils.newInstance(type); - } - - public static List> getAllSuperClasses(Class type, Class ignoredType) { - List> superClasses = new ArrayList<>(); - Class superClass = type.getSuperclass(); - while (superClass != null) { - if (superClass != ignoredType) { - superClasses.add(superClass); - } - superClass = superClass.getSuperclass(); - } - Collections.reverse(superClasses); - return superClasses; - } - - public static Set getFieldNames(Class type) { - Set fieldNames = new LinkedHashSet<>(); - for (Field field : type.getDeclaredFields()) { - fieldNames.add(field.getName()); - } - return fieldNames; - } - -} diff --git a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/StringUtils.java b/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/StringUtils.java deleted file mode 100644 index 277c0e4874a6960997bc2cabf30002cffda894ac..0000000000000000000000000000000000000000 --- a/spring-domain-core/src/main/java/com/gitee/spring/domain/core/utils/StringUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.gitee.spring.domain.core.utils; - -import cn.hutool.core.util.StrUtil; - -public class StringUtils { - - public static String[] toUnderlineCase(String... columns) { - String[] newColumns = new String[columns.length]; - for (int index = 0; index < columns.length; index++) { - newColumns[index] = StrUtil.toUnderlineCase(columns[index]); - } - return newColumns; - } - - public static boolean isLike(String value) { - return value.startsWith("%") && value.endsWith("%"); - } - - public static String stripLike(String value) { - return StrUtil.strip(value, "%"); - } - -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/annotation/EnableEvent.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/annotation/EnableEvent.java deleted file mode 100644 index 297b2e5ac33376c2b5a2f719cd32ba37914865f5..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/annotation/EnableEvent.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.spring.domain.event.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface EnableEvent { -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/annotation/EntityListener.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/annotation/EntityListener.java deleted file mode 100644 index fdfdf24e31a45570a86ecf8d59a60745aef39688..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/annotation/EntityListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.spring.domain.event.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface EntityListener { - - Class value(); - -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/api/EventListener.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/api/EventListener.java deleted file mode 100644 index 36a3da88006f3992155223b512c89faa09a973f9..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/api/EventListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.spring.domain.event.api; - -import com.gitee.spring.domain.event.entity.RepositoryEvent; - -public interface EventListener { - - void onApplicationEvent(RepositoryEvent repositoryEvent); - -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/config/DomainEventConfiguration.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/config/DomainEventConfiguration.java deleted file mode 100644 index f64bbe9f1f5b4c84af692f980a6d1e9f312b7f7c..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/config/DomainEventConfiguration.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.spring.domain.event.config; - -import com.gitee.spring.domain.event.listener.RepositoryListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; - -@Order(-100) -@Configuration -public class DomainEventConfiguration { - - @Bean - public RepositoryListener repositoryListener() { - return new RepositoryListener(); - } - -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/entity/OperationType.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/entity/OperationType.java deleted file mode 100644 index 449825c030b28b45f2fef0df626076bbc07ccadb..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/entity/OperationType.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.gitee.spring.domain.event.entity; - -public enum OperationType { - INSERT, UPDATE, DELETE -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/entity/RepositoryEvent.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/entity/RepositoryEvent.java deleted file mode 100644 index 5b96f34d6df1a06ed797280c781e756e79b4b5c7..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/entity/RepositoryEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.spring.domain.event.entity; - -import com.gitee.spring.domain.core.entity.BoundedContext; -import com.gitee.spring.domain.core.repository.AbstractRepository; -import lombok.Getter; -import lombok.Setter; -import org.springframework.context.ApplicationEvent; - -@Getter -@Setter -public class RepositoryEvent extends ApplicationEvent { - - private String methodName; - private OperationType operationType; - private BoundedContext boundedContext; - private Object entity; - private Object example; - private Object primaryKey; - - public RepositoryEvent(AbstractRepository repository) { - super(repository); - } - -} diff --git a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/repository/AbstractEventRepository.java b/spring-domain-event/src/main/java/com/gitee/spring/domain/event/repository/AbstractEventRepository.java deleted file mode 100644 index e6150751da91aa48d1fa8386ddea84f71acf44f7..0000000000000000000000000000000000000000 --- a/spring-domain-event/src/main/java/com/gitee/spring/domain/event/repository/AbstractEventRepository.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.gitee.spring.domain.event.repository; - -import com.gitee.spring.domain.core.repository.AbstractBatchRepository; -import com.gitee.spring.domain.core.repository.AbstractRepository; -import com.gitee.spring.domain.core.repository.ConfiguredRepository; -import com.gitee.spring.domain.event.annotation.EnableEvent; -import org.springframework.core.annotation.AnnotationUtils; - -public abstract class AbstractEventRepository extends AbstractBatchRepository { - - protected boolean enableEvent; - - @Override - public void afterPropertiesSet() throws Exception { - EnableEvent enableEvent = AnnotationUtils.getAnnotation(this.getClass(), EnableEvent.class); - this.enableEvent = enableEvent != null; - super.afterPropertiesSet(); - } - - @Override - protected ConfiguredRepository postProcessRepository(ConfiguredRepository configuredRepository) { - configuredRepository = super.postProcessRepository(configuredRepository); - AbstractRepository abstractRepository = configuredRepository.getProxyRepository(); - if (abstractRepository instanceof AbstractEventRepository) { - return configuredRepository; - } - return enableEvent ? new EventRepository(configuredRepository, applicationContext) : configuredRepository; - } - -} diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/annotation/Root.java b/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/annotation/Root.java deleted file mode 100644 index 396d6d124ad34f0d6ce377c22b2f2570a9f84a19..0000000000000000000000000000000000000000 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/annotation/Root.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.spring.domain.injection.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Root { -} diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/api/TypeDomainResolver.java b/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/api/TypeDomainResolver.java deleted file mode 100644 index 726cc96ce5e172eb4c2a9af629af582fd9295861..0000000000000000000000000000000000000000 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/api/TypeDomainResolver.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.gitee.spring.domain.injection.api; - -import com.gitee.spring.domain.injection.entity.DomainDefinition; - -public interface TypeDomainResolver { - - boolean isUnderScanPackage(Class typeToMatch); - - DomainDefinition matchDomainDefinition(Class typeToMatch); - - void checkDomain(Class targetType, Class injectedType); - - void checkDomainProtection(Class targetType); - -} diff --git a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/entity/DomainDefinition.java b/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/entity/DomainDefinition.java deleted file mode 100644 index 0f6787ab05eddb090b902937ab7c73d194e214ea..0000000000000000000000000000000000000000 --- a/spring-domain-injection/src/main/java/com/gitee/spring/domain/injection/entity/DomainDefinition.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.gitee.spring.domain.injection.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class DomainDefinition { - private String name; - private String pattern; - private String protect; -} diff --git a/spring-domain-web/src/main/java/com/gitee/spring/domain/web/annotation/EnableWeb.java b/spring-domain-web/src/main/java/com/gitee/spring/domain/web/annotation/EnableWeb.java deleted file mode 100644 index 3e25dd1cefa23b6e6b0071d513b08b751763cc44..0000000000000000000000000000000000000000 --- a/spring-domain-web/src/main/java/com/gitee/spring/domain/web/annotation/EnableWeb.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.spring.domain.web.annotation; - -import java.lang.annotation.*; - -@Inherited -@Documented -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface EnableWeb { -} diff --git a/spring-domain-web/src/main/java/com/gitee/spring/domain/web/repository/AbstractWebRepository.java b/spring-domain-web/src/main/java/com/gitee/spring/domain/web/repository/AbstractWebRepository.java deleted file mode 100644 index 9f1dc70b4200444470912a8ce186e6beac58308e..0000000000000000000000000000000000000000 --- a/spring-domain-web/src/main/java/com/gitee/spring/domain/web/repository/AbstractWebRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.gitee.spring.domain.web.repository; - -import com.gitee.spring.domain.coating.repository.AbstractChainRepository; -import com.gitee.spring.domain.web.annotation.EnableWeb; -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.springframework.core.annotation.AnnotationUtils; - -@Data -@EqualsAndHashCode(callSuper = false) -public abstract class AbstractWebRepository extends AbstractChainRepository { - - protected boolean enableWeb; - - @Override - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - EnableWeb enableWeb = AnnotationUtils.getAnnotation(this.getClass(), EnableWeb.class); - this.enableWeb = enableWeb != null; - } - -} diff --git a/static/img/divide.png b/static/img/divide.png deleted file mode 100644 index c012593f56bc5691b80b23d351138d8cd71ea753..0000000000000000000000000000000000000000 Binary files a/static/img/divide.png and /dev/null differ diff --git a/static/img/layer.png b/static/img/layer.png deleted file mode 100644 index ffd57f7339f51b48d251c9aa1d5e5d2fdc92fbc4..0000000000000000000000000000000000000000 Binary files a/static/img/layer.png and /dev/null differ diff --git a/static/img/model.png b/static/img/model.png deleted file mode 100644 index 6fecf047de2f98df13bd1f40e2a3772a62ab3f0b..0000000000000000000000000000000000000000 Binary files a/static/img/model.png and /dev/null differ diff --git a/static/img/modify.png b/static/img/modify.png deleted file mode 100644 index 237b039c9df6997f961999a3e8e12d657ccd71f2..0000000000000000000000000000000000000000 Binary files a/static/img/modify.png and /dev/null differ