images = new ArrayList<>();
+ images.add(UiConsts.IMAGE_LOGO_1024);
+ images.add(UiConsts.IMAGE_LOGO_512);
+ images.add(UiConsts.IMAGE_LOGO_256);
+ images.add(UiConsts.IMAGE_LOGO_128);
+ images.add(UiConsts.IMAGE_LOGO_64);
+ images.add(UiConsts.IMAGE_LOGO_48);
+ images.add(UiConsts.IMAGE_LOGO_32);
+ images.add(UiConsts.IMAGE_LOGO_24);
+ images.add(UiConsts.IMAGE_LOGO_16);
+ jFrame.setIconImages(images);
+ }
+}
diff --git a/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/ScrollUtil.java b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/ScrollUtil.java
new file mode 100644
index 0000000..9c763f8
--- /dev/null
+++ b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/ScrollUtil.java
@@ -0,0 +1,19 @@
+package io.fluent.pcinfo.util;
+
+import javax.swing.*;
+
+/**
+ * some functions about scroll
+ *
+ * @author RememBerBer
+ * @since 2021/11/23.
+ */
+public class ScrollUtil {
+
+ public static void smoothPane(JScrollPane scrollPane) {
+ scrollPane.getVerticalScrollBar().setUnitIncrement(14);
+ scrollPane.getHorizontalScrollBar().setUnitIncrement(14);
+ scrollPane.getVerticalScrollBar().setDoubleBuffered(true);
+ scrollPane.getHorizontalScrollBar().setDoubleBuffered(true);
+ }
+}
diff --git a/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/SystemUtil.java b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/SystemUtil.java
new file mode 100644
index 0000000..4a8d454
--- /dev/null
+++ b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/SystemUtil.java
@@ -0,0 +1,42 @@
+package io.fluent.pcinfo.util;
+
+import java.io.File;
+
+/**
+ * System util
+ *
+ * @author RememBerBer
+ * @since 2021/11/08.
+ */
+public class SystemUtil {
+ private static final String OS_NAME = System.getProperty("os.name");
+ private static final String OS_ARCH = System.getProperty("os.arch");
+ private static final String VM_VENDOR = System.getProperty("java.vm.vendor");
+ private static final String USER_HOME = System.getProperty("user.home");
+ public static final String CONFIG_HOME = USER_HOME + File.separator + ".MooInfo";
+
+ /**
+ * log file dir
+ */
+ public final static String LOG_DIR = USER_HOME + File.separator + ".MooInfo" + File.separator + "logs" + File.separator;
+
+ public static boolean isMacOs() {
+ return OS_NAME.contains("Mac");
+ }
+
+ public static boolean isMacM1() {
+ return OS_NAME.contains("Mac") && "aarch64".equals(OS_ARCH);
+ }
+
+ public static boolean isWindowsOs() {
+ return OS_NAME.contains("Windows");
+ }
+
+ public static boolean isLinuxOs() {
+ return OS_NAME.contains("Linux");
+ }
+
+ public static boolean isJBR() {
+ return VM_VENDOR.contains("JetBrains");
+ }
+}
\ No newline at end of file
diff --git a/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/UIUtil.java b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/UIUtil.java
new file mode 100644
index 0000000..fa6e554
--- /dev/null
+++ b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/UIUtil.java
@@ -0,0 +1,65 @@
+package io.fluent.pcinfo.util;
+
+import io.fluent.pcinfo.App;
+import lombok.extern.slf4j.Slf4j;
+
+import java.awt.*;
+
+/**
+ * UI custom tools
+ *
+ * @author RememBerBer
+ * @since 2021/11/10.
+ */
+@Slf4j
+public class UIUtil {
+
+ /**
+ * Get screen specifications
+ *
+ * author by darcula@com.bulenkov
+ * see https://github.com/bulenkov/Darcula
+ *
+ * @return
+ */
+ public static float getScreenScale() {
+ int dpi = 96;
+
+ try {
+ dpi = Toolkit.getDefaultToolkit().getScreenResolution();
+ } catch (HeadlessException var2) {
+ }
+
+ float scale = 1.0F;
+ if (dpi < 120) {
+ scale = 1.0F;
+ } else if (dpi < 144) {
+ scale = 1.25F;
+ } else if (dpi < 168) {
+ scale = 1.5F;
+ } else if (dpi < 192) {
+ scale = 1.75F;
+ } else {
+ scale = 2.0F;
+ }
+
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ log.info("screen dpi:{},width:{},height:{}", dpi, screenSize.getWidth(), screenSize.getHeight());
+
+ return scale;
+ }
+
+ /**
+ * the theme is dark or not
+ *
+ * @return
+ */
+ public static boolean isDarkLaf() {
+ return "Darcula".equals(App.config.getTheme())
+ || "Darcula(Recommended)".equals(App.config.getTheme())
+ || "Flat Dark".equals(App.config.getTheme())
+ || "Flat Darcula".equals(App.config.getTheme())
+ || "Dark purple".equals(App.config.getTheme())
+ || "Flat Darcula(Recommended)".equals(App.config.getTheme());
+ }
+}
diff --git a/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/UpgradeUtil.java b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/UpgradeUtil.java
new file mode 100644
index 0000000..cab1f55
--- /dev/null
+++ b/fluent-apps/pcinfo/src/main/java/io/fluent/pcinfo/util/UpgradeUtil.java
@@ -0,0 +1,136 @@
+package io.fluent.pcinfo.util;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import io.fluent.pcinfo.App;
+import io.fluent.pcinfo.bean.VersionSummary;
+import io.fluent.pcinfo.ui.UiConsts;
+import io.fluent.pcinfo.ui.dialog.UpdateInfoDialog;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.swing.*;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Upgrade tool class
+ *
+ * @author RememBerBer
+ * @since 2021/11/08.
+ */
+@Slf4j
+public class UpgradeUtil {
+
+ public static void checkUpdate(boolean initCheck) {
+ // current version
+ String currentVersion = UiConsts.APP_VERSION;
+
+ // Get information about the latest version from github
+ String versionSummaryJsonContent = HttpUtil.get(UiConsts.CHECK_VERSION_URL);
+ if (StrUtil.isEmpty(versionSummaryJsonContent) && !initCheck) {
+ JOptionPane.showMessageDialog(App.mainFrame,
+ "Check for timeouts, follow GitHub Release!", "Network error",
+ JOptionPane.INFORMATION_MESSAGE);
+ return;
+ } else if (StrUtil.isEmpty(versionSummaryJsonContent) || versionSummaryJsonContent.contains("404: Not Found")) {
+ return;
+ }
+ versionSummaryJsonContent = versionSummaryJsonContent.replace("\n", "");
+
+ VersionSummary versionSummary = JSONUtil.toBean(versionSummaryJsonContent, VersionSummary.class);
+ // The latest version
+ String newVersion = versionSummary.getCurrentVersion();
+ String versionIndexJsonContent = versionSummary.getVersionIndex();
+ // Version index
+ Map versionIndexMap = JSONUtil.toBean(versionIndexJsonContent, Map.class);
+ // list of version details
+ List versionDetailList = versionSummary.getVersionDetailList();
+
+ if (newVersion.compareTo(currentVersion) > 0) {
+ // The current version index
+ int currentVersionIndex = Integer.parseInt(versionIndexMap.get(currentVersion));
+ // Version update log:
+ StringBuilder versionLogBuilder = new StringBuilder("Surprise the new version! Download it now? ");
+ VersionSummary.Version version;
+ for (int i = currentVersionIndex + 1; i < versionDetailList.size(); i++) {
+ version = versionDetailList.get(i);
+ versionLogBuilder.append("").append(version.getVersion()).append(" ");
+ versionLogBuilder.append("").append(version.getTitle()).append(" ");
+ versionLogBuilder.append("").append(version.getLog().replaceAll("\\n", "
")).append("
");
+ }
+ String versionLog = versionLogBuilder.toString();
+
+ UpdateInfoDialog updateInfoDialog = new UpdateInfoDialog();
+ updateInfoDialog.setHtmlText(versionLog);
+ updateInfoDialog.setNewVersion(newVersion);
+ updateInfoDialog.pack();
+ updateInfoDialog.setVisible(true);
+ } else {
+ if (!initCheck) {
+ JOptionPane.showMessageDialog(App.mainFrame,
+ "It's the latest version!", "Congratulations",
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+ }
+ }
+
+ /**
+ * Smooth upgrade
+ * The version update scripts and sql methods involved are as idempotent as possible to avoid repeated upgrade operations due to unusual interruptions such as power failures and deaths during the upgrade process
+ */
+ public static void smoothUpgrade() {
+ // Get the current version
+ String currentVersion = UiConsts.APP_VERSION;
+ // Get the before upgrade version
+ String beforeVersion = App.config.getBeforeVersion();
+
+ if (currentVersion.compareTo(beforeVersion) <= 0) {
+ // If both are consistent, no upgrade action is performed
+ return;
+ } else {
+ log.info("Smooth upgrade begins");
+
+ // Then take the index for both versions
+ String versionSummaryJsonContent = FileUtil.readString(UiConsts.class.getResource("/version_summary.json"), CharsetUtil.UTF_8);
+ versionSummaryJsonContent = versionSummaryJsonContent.replace("\n", "");
+ VersionSummary versionSummary = JSONUtil.toBean(versionSummaryJsonContent, VersionSummary.class);
+ String versionIndex = versionSummary.getVersionIndex();
+ Map versionIndexMap = JSONUtil.toBean(versionIndex, Map.class);
+ int currentVersionIndex = Integer.parseInt(versionIndexMap.get(currentVersion));
+ int beforeVersionIndex = Integer.parseInt(versionIndexMap.get(beforeVersion));
+ log.info("Older version{}", beforeVersion);
+ log.info("Current version{}", currentVersion);
+ // Traverses the index range
+ beforeVersionIndex++;
+ for (int i = beforeVersionIndex; i <= currentVersionIndex; i++) {
+ log.info("Update the version index {} begin", i);
+ // Perform updates to each version index, from far to nearby time
+ upgrade(i);
+ log.info("Update the version index {} finished", i);
+ }
+
+ // If the upgrade is complete and successful, the version number prior to the upgrade is assigned to the current version
+ App.config.setBeforeVersion(currentVersion);
+ App.config.save();
+ log.info("Smooth upgrade ends");
+ }
+ }
+
+ /**
+ * Execute the upgrade script
+ *
+ * @param versionIndex Version index
+ */
+ private static void upgrade(int versionIndex) {
+ log.info("Start with the upgrade script, version index:{}", versionIndex);
+ switch (versionIndex) {
+ case 21:
+ break;
+ default:
+ }
+ log.info("The upgrade script ends, the version index:{}", versionIndex);
+ }
+}
diff --git a/fluent-apps/pom.xml b/fluent-apps/pom.xml
index db16297..4db3ace 100644
--- a/fluent-apps/pom.xml
+++ b/fluent-apps/pom.xml
@@ -12,7 +12,8 @@
fluent-apps
pom
- feeds
+ pcinfo
+ workspace
diff --git a/fluent-apps/feeds/pom.xml b/fluent-apps/workspace/pom.xml
similarity index 66%
rename from fluent-apps/feeds/pom.xml
rename to fluent-apps/workspace/pom.xml
index 05344d0..e2e0407 100644
--- a/fluent-apps/feeds/pom.xml
+++ b/fluent-apps/workspace/pom.xml
@@ -9,11 +9,14 @@
1.0-SNAPSHOT
- feeds
+ workspace
+ 17
+ 17
UTF-8
+
@@ -32,7 +35,6 @@
erupt-job
${erupt.version}
-
xyz.erupt
@@ -66,15 +68,57 @@
4.4.0
+
+ io.fluent
+ fluent-excel
+ ${fluent.version}
+
+
+ io.fluent
+ fluent-mindmap
+ ${fluent.version}
+
+
+ io.fluent
+ fluent-erupts-base
+ ${fluent.version}
+
+
io.fluent
fleunt-github
${fluent.version}
+
+
+
+
+
cn.hutool
hutool-all
+
+ io.fluent
+ fluent-quickdao
+ 1.0-SNAPSHOT
+
+
+ io.fluent
+ fluent-openapi
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+
+
+
+
+
+
@@ -101,4 +145,5 @@
+
\ No newline at end of file
diff --git a/fluent-apps/feeds/src/main/java/io/fluent/datafam/DataFeedFarmApp.java b/fluent-apps/workspace/src/main/java/io/fluent/WorkspaceApplication.java
similarity index 67%
rename from fluent-apps/feeds/src/main/java/io/fluent/datafam/DataFeedFarmApp.java
rename to fluent-apps/workspace/src/main/java/io/fluent/WorkspaceApplication.java
index 1f83913..ba3e056 100644
--- a/fluent-apps/feeds/src/main/java/io/fluent/datafam/DataFeedFarmApp.java
+++ b/fluent-apps/workspace/src/main/java/io/fluent/WorkspaceApplication.java
@@ -1,4 +1,4 @@
-package io.fluent.datafam;
+package io.fluent;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -10,8 +10,12 @@
@EnableAsync
@EruptScan
@EntityScan
-public class DataFeedFarmApp {
+public class WorkspaceApplication {
+ /**
+ * QA Management Application Entrypoint
+ * @param args
+ */
public static void main(String[] args) {
- SpringApplication.run(DataFeedFarmApp.class);
+ SpringApplication.run(WorkspaceApplication.class);
}
}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/FluentProductConfigModule.java b/fluent-apps/workspace/src/main/java/io/fluent/base/FluentProductConfigModule.java
new file mode 100644
index 0000000..d4f42ec
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/FluentProductConfigModule.java
@@ -0,0 +1,65 @@
+package io.fluent.base;
+
+import io.fluent.base.masterdata.model.MasterData;
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.base.project.model.ProjectModel;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import xyz.erupt.core.annotation.EruptScan;
+import xyz.erupt.core.constant.MenuTypeEnum;
+import xyz.erupt.core.module.EruptModule;
+import xyz.erupt.core.module.EruptModuleInvoke;
+import xyz.erupt.core.module.MetaMenu;
+import xyz.erupt.core.module.ModuleInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@ComponentScan
+@EntityScan
+@EruptScan
+@EnableConfigurationProperties
+public class FluentProductConfigModule implements EruptModule {
+
+ public FluentProductConfigModule() {
+ }
+
+ @Override
+ public ModuleInfo info() {
+ return ModuleInfo.builder().name("fluent-product").build();
+ }
+
+ @Override
+ public void run() {
+ EruptModule.super.run();
+ }
+
+ @Override
+ public List initMenus() {
+ List menus = new ArrayList<>();
+ menus.add(MetaMenu.createRootMenu("$fluent-master", "产品配置", "fa fa-product-hunt", 90));
+ MetaMenu productMetaMenu = MetaMenu.createEruptClassMenu(ProductModuleModel.class, menus.get(0), 0, MenuTypeEnum.TABLE);
+ productMetaMenu.setIcon("fa fa-group");
+ productMetaMenu.setName("产品元数据");
+ productMetaMenu.setCode("$product-meta");
+ menus.add(productMetaMenu);
+ MetaMenu masterDataMenu = MetaMenu.createEruptClassMenu(MasterData.class, menus.get(0), 1, MenuTypeEnum.TABLE);
+ masterDataMenu.setIcon("fa fa-times");
+ masterDataMenu.setName("产品字典表配置");
+ masterDataMenu.setCode("$master-data");
+ menus.add(masterDataMenu);
+ MetaMenu projectMenu = MetaMenu.createEruptClassMenu(ProjectModel.class, menus.get(0), 2, MenuTypeEnum.TABLE);
+ projectMenu.setIcon("fa fa-linode");
+ projectMenu.setName("项目配置");
+ projectMenu.setCode("$project-meta");
+ menus.add(projectMenu);
+ return menus;
+ }
+
+ static {
+ EruptModuleInvoke.addEruptModule(FluentProductConfigModule.class);
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/README.md b/fluent-apps/workspace/src/main/java/io/fluent/base/README.md
new file mode 100644
index 0000000..9fb066c
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/README.md
@@ -0,0 +1,8 @@
+# README
+
+shared component:
+
+- master data: shared configurations
+- upload data: upload component
+- product: product module
+- project: project module
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/masterdata/model/MasterData.java b/fluent-apps/workspace/src/main/java/io/fluent/base/masterdata/model/MasterData.java
new file mode 100644
index 0000000..e8d0150
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/masterdata/model/MasterData.java
@@ -0,0 +1,76 @@
+package io.fluent.base.masterdata.model;
+
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlagVo;
+import lombok.Data;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.InputType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.annotation.sub_field.sub_edit.TagsType;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+
+@Erupt(name = "产品字典值配置", power = @Power(importable = true, export = true))
+@Table(name = "master_data")
+@Entity
+@Data
+public class MasterData extends ModelWithValidFlagVo {
+
+ @EruptField(
+ views = @View(title = "分类"),
+ edit = @Edit(
+ search = @Search(vague = true),
+ title = "获取可选种类",
+ type = EditType.TAGS,
+ desc = "动态获取可选种类",
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct category from master_data where valid=true"
+ ))
+ )
+ private String category;
+
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String name;
+
+ @EruptField(
+ views = @View(
+ title = "详细描述"
+ ),
+ edit = @Edit(
+ title = "详细描述",
+ type = EditType.INPUT,
+ inputType = @InputType
+ )
+ )
+ private String detail;
+
+ @EruptField(
+ views = @View(
+ title = "代号"
+ ),
+ edit = @Edit(
+ title = "代号",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String code;
+
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/masterdata/repo/MasterDataRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/base/masterdata/repo/MasterDataRepo.java
new file mode 100644
index 0000000..2618156
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/masterdata/repo/MasterDataRepo.java
@@ -0,0 +1,15 @@
+package io.fluent.base.masterdata.repo;
+
+import io.fluent.base.masterdata.model.MasterData;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface MasterDataRepo extends JpaRepository, JpaSpecificationExecutor {
+
+ Optional findMasterDataByCode(String code);
+
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/package-info.java b/fluent-apps/workspace/src/main/java/io/fluent/base/package-info.java
new file mode 100644
index 0000000..b1b2672
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/package-info.java
@@ -0,0 +1 @@
+package io.fluent.base;
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/product/model/ProductModuleModel.java b/fluent-apps/workspace/src/main/java/io/fluent/base/product/model/ProductModuleModel.java
new file mode 100644
index 0000000..a86390c
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/product/model/ProductModuleModel.java
@@ -0,0 +1,140 @@
+package io.fluent.base.product.model;
+
+import io.fluent.base.model.ModelWithValidFlagVo;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_erupt.Tree;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.ChoiceType;
+import xyz.erupt.annotation.sub_field.sub_edit.InputType;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.toolkit.handler.SqlChoiceFetchHandler;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Erupt(name = "产品模块配置",
+ power = @Power(importable = true, export = true),
+ tree = @Tree(pid = "parent.id"))
+@Entity
+@Table(name = "products")
+public class ProductModuleModel extends ModelWithValidFlagVo {
+
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search,
+ notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String name;
+
+ @EruptField(
+ views = @View(
+ title = "代号"
+ ),
+ edit = @Edit(
+ title = "代号",
+ type = EditType.INPUT, search = @Search,
+ notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String code;
+
+ @EruptField(
+ views = @View(
+ title = "详细描述"
+ ),
+ edit = @Edit(
+ title = "详细描述",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String details;
+
+ @EruptField(
+ views = @View(title = "类型"),
+ edit = @Edit(
+ search = @Search,
+ title = "获取可选类型",
+ type = EditType.CHOICE,
+ desc = "动态获取可选类型",
+ choiceType = @ChoiceType(
+ fetchHandler = SqlChoiceFetchHandler.class,
+ fetchHandlerParams = "select id,name from master_data where category='PRODUCT'"
+ ))
+ )
+ private String metaType;
+
+ @ManyToOne
+ @EruptField(
+ edit = @Edit(
+ title = "上级树节点",
+ type = EditType.REFERENCE_TREE,
+ referenceTreeType = @ReferenceTreeType(pid = "parent.id")
+ )
+ )
+ private ProductModuleModel parent;
+
+
+ @Column(length = 36, nullable = true, updatable = false)
+ private String uuid = UUID.randomUUID().toString();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getDetails() {
+ return details;
+ }
+
+ public void setDetails(String details) {
+ this.details = details;
+ }
+
+ public String getMetaType() {
+ return metaType;
+ }
+
+ public void setMetaType(String metaType) {
+ this.metaType = metaType;
+ }
+
+ public ProductModuleModel getParent() {
+ return parent;
+ }
+
+ public void setParent(ProductModuleModel parent) {
+ this.parent = parent;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/product/model/ProductModuleValidFlagVo.java b/fluent-apps/workspace/src/main/java/io/fluent/base/product/model/ProductModuleValidFlagVo.java
new file mode 100644
index 0000000..b267168
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/product/model/ProductModuleValidFlagVo.java
@@ -0,0 +1,47 @@
+package io.fluent.base.product.model;
+
+import io.fluent.base.model.ModelWithValidFlagVo;
+import lombok.Getter;
+import lombok.Setter;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+
+@MappedSuperclass
+@Getter
+@Setter
+public class ProductModuleValidFlagVo extends ModelWithValidFlagVo {
+ @ManyToOne
+ @JoinColumn(name = "product_id")
+ @EruptField(
+ views = @View(title = "产品名称",column = "details"),
+ edit = @Edit(
+ search = @Search,
+ title = "产品选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ pid = "parent.id"))
+ )
+ private ProductModuleModel product;
+
+ @ManyToOne
+ @JoinColumn(name = "module_id")
+ @EruptField(
+ views = @View(title = "模块名称",column = "details"),
+ edit = @Edit(title = "模块选择", search = @Search, type = EditType.REFERENCE_TREE,
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ dependField = "product",
+ dependColumn = "parent.id"
+ ))
+ )
+ private ProductModuleModel module;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/product/package-info.java b/fluent-apps/workspace/src/main/java/io/fluent/base/product/package-info.java
new file mode 100644
index 0000000..15f9d3f
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/product/package-info.java
@@ -0,0 +1 @@
+package io.fluent.base.product;
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/product/repo/ProductModuleRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/base/product/repo/ProductModuleRepo.java
new file mode 100644
index 0000000..7898e5f
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/product/repo/ProductModuleRepo.java
@@ -0,0 +1,18 @@
+package io.fluent.base.product.repo;
+
+
+import io.fluent.base.product.model.ProductModuleModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface ProductModuleRepo extends JpaRepository, JpaSpecificationExecutor {
+
+ Optional findProductByNameAndValid(String name, boolean valid);
+
+ Optional findProductByCodeAndValid(String codeName, boolean valid);
+ Optional findProductByParentIdAndNameAndValid(Long parentId, String name, boolean valid);
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/product/service/ProductModuleService.java b/fluent-apps/workspace/src/main/java/io/fluent/base/product/service/ProductModuleService.java
new file mode 100644
index 0000000..0c42dac
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/product/service/ProductModuleService.java
@@ -0,0 +1,57 @@
+package io.fluent.base.product.service;
+
+import io.fluent.builtin.PingYinUtils;
+import io.fluent.base.product.repo.ProductModuleRepo;
+import io.fluent.base.proxies.AuditDataEnhancerProxy;
+import io.fluent.base.masterdata.repo.MasterDataRepo;
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.base.masterdata.model.MasterData;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Optional;
+
+@Service
+public class ProductModuleService {
+ @Resource
+ private ProductModuleRepo metaRepo;
+
+ @Resource
+ private MasterDataRepo masterDataRepo;
+
+ @Resource
+ AuditDataEnhancerProxy dataEnhancerProxy;
+
+ public ProductModuleModel createModuleIfNotExist(Long productId, String moduleName, String updater) {
+ Optional meta = metaRepo.findProductByParentIdAndNameAndValid(productId,
+ moduleName, true);
+ if (meta.isPresent()) return meta.get();
+ ProductModuleModel parent = new ProductModuleModel();
+ parent.setId(productId);
+ ProductModuleModel module = new ProductModuleModel();
+ module.setName(moduleName);
+ module.setDetails(moduleName);
+ module.setParent(parent);
+ module.setCode(PingYinUtils.convertToPinyinAbbreviation(moduleName));
+ MasterData data = masterDataRepo.findMasterDataByCode("MODULE").get();
+ module.setMetaType(data.getId().toString());
+ dataEnhancerProxy.enhanceTimeAndUserAuditData(module,updater);
+ return metaRepo.save(module);
+ }
+
+ public ProductModuleModel findApiServiceProduct() {
+ String API_SERVICE = "API";
+ Optional meta = metaRepo.findProductByCodeAndValid(API_SERVICE, true);
+ if (meta.isPresent()) return meta.get();
+ throw new RuntimeException("Please config API Service as a Product in Product Meta");
+ }
+
+ public ProductModuleModel createApiModuleIfNotExist(String moduleName,String updater) {
+ ProductModuleModel parent = findApiServiceProduct();
+ return createModuleIfNotExist(parent.getId(), moduleName,updater);
+ }
+
+ public ProductModuleModel findByName(String productName) {
+ return metaRepo.findProductByNameAndValid(productName, true).orElse(null);
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/project/model/ProjectModel.java b/fluent-apps/workspace/src/main/java/io/fluent/base/project/model/ProjectModel.java
new file mode 100644
index 0000000..573eace
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/project/model/ProjectModel.java
@@ -0,0 +1,89 @@
+package io.fluent.base.project.model;
+
+
+import io.fluent.base.model.ModelWithValidFlagVo;
+import io.fluent.base.product.model.ProductModuleModel;
+import lombok.Data;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_erupt.Tree;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.InputType;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Erupt(name = "项目",
+ power = @Power(importable = true, export = true),
+ tree = @Tree(pid = "parent.id"))
+@Entity
+@Table(name = "projects")
+@Data
+public class ProjectModel extends ModelWithValidFlagVo {
+
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search,
+ notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String name;
+
+ @EruptField(
+ views = @View(
+ title = "代号"
+ ),
+ edit = @Edit(
+ title = "代号",
+ type = EditType.INPUT, search = @Search,
+ notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String code;
+
+ @EruptField(
+ views = @View(
+ title = "详细描述"
+ ),
+ edit = @Edit(
+ title = "详细描述",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String details;
+
+ @ManyToOne
+ @EruptField(
+ edit = @Edit(
+ title = "产品列表",
+ type = EditType.REFERENCE_TREE,
+ referenceTreeType = @ReferenceTreeType(pid = "parent.id")
+ )
+ )
+ private ProductModuleModel productId;
+
+ @ManyToOne
+ @EruptField(
+ edit = @Edit(
+ title = "上级树节点",
+ type = EditType.REFERENCE_TREE,
+ referenceTreeType = @ReferenceTreeType(pid = "parent.id")
+ )
+ )
+ private ProjectModel parent;
+
+ @Column(length = 36, nullable = false, updatable = false)
+ private String uuid = UUID.randomUUID().toString();
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/base/project/repo/ProjectModelRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/base/project/repo/ProjectModelRepo.java
new file mode 100644
index 0000000..098b228
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/base/project/repo/ProjectModelRepo.java
@@ -0,0 +1,18 @@
+package io.fluent.base.project.repo;
+
+
+import io.fluent.base.product.model.ProductModuleModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface ProjectModelRepo extends JpaRepository, JpaSpecificationExecutor {
+
+ Optional findProductByNameAndValid(String name, boolean valid);
+
+ Optional findProductByCodeAndValid(String codeName, boolean valid);
+ Optional findProductByParentIdAndNameAndValid(Long parentId, String name, boolean valid);
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/FluentQAApiModule.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/FluentQAApiModule.java
new file mode 100644
index 0000000..2a8570a
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/FluentQAApiModule.java
@@ -0,0 +1,125 @@
+package io.fluent.qtm;
+
+
+import io.fluent.qtm.api.model.*;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import xyz.erupt.core.annotation.EruptScan;
+import xyz.erupt.core.constant.MenuTypeEnum;
+import xyz.erupt.core.module.EruptModule;
+import xyz.erupt.core.module.EruptModuleInvoke;
+import xyz.erupt.core.module.MetaMenu;
+import xyz.erupt.core.module.ModuleInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@Configuration
+@ComponentScan
+@EntityScan
+@EruptScan
+@EnableConfigurationProperties
+public class FluentQAApiModule implements EruptModule {
+ public FluentQAApiModule() {
+ }
+
+ @Override
+ public ModuleInfo info() {
+ return ModuleInfo.builder().name("fluent-api").build();
+ }
+
+ @Override
+ public void run() {
+ EruptModule.super.run();
+ }
+
+ /**
+ * API管理:
+ *
+ * 1. API 仓库管理
+ * 2. API 接口定义
+ * 3. API 接口录制记录
+ * 4. API 接口测试
+ *
+ * @return
+ */
+ @Override
+ public List initMenus() {
+ List menus = new ArrayList<>();
+ menus.add(MetaMenu.createRootMenu("$APIMgr", "接口管理", "fa fa-exchange", 1));
+
+ MetaMenu menuForAdded = MetaMenu.createEruptClassMenu(RemoteApi.class,
+ menus.get(0), 1, MenuTypeEnum.TABLE);
+ menuForAdded.setIcon("fa fa-scissors");
+ menuForAdded.setName("API清单");
+ menuForAdded.setCode("$API-List");
+ menus.add(menuForAdded);
+
+ MetaMenu rawApiTestCaseMenu = MetaMenu.createEruptClassMenu(RawApiTestCase.class,
+ menus.get(0), 1, MenuTypeEnum.TABLE);
+ rawApiTestCaseMenu.setIcon("fa fa-scissors");
+ rawApiTestCaseMenu.setName("API生成原始测试用例");
+ rawApiTestCaseMenu.setCode("$API-TC-GEN");
+ menus.add(rawApiTestCaseMenu);
+
+ MetaMenu apiMonitorRecordMenu = MetaMenu.createEruptClassMenu(ApiMonitorRecord.class,
+ menus.get(0), 2, MenuTypeEnum.TABLE);
+ apiMonitorRecordMenu.setIcon("fa fa-repeat");
+ apiMonitorRecordMenu.setName("API录制记录");
+ apiMonitorRecordMenu.setCode("$API-Record");
+ menus.add(apiMonitorRecordMenu);
+
+ MetaMenu apiTestRecord = MetaMenu.createEruptClassMenu(
+ ApiTestRecord
+ .class,
+ menus.get(0), 3, MenuTypeEnum.TABLE);
+ apiTestRecord.setIcon("fa fa-thumbs-up");
+ apiTestRecord.setName("API测试结果记录");
+ apiTestRecord.setCode("$API-TestResult");
+ menus.add(apiTestRecord);
+
+ MetaMenu apiTestScenarioMenu = MetaMenu.createEruptClassMenu(
+ ApiTestScenario
+ .class,
+ menus.get(0), 4, MenuTypeEnum.TABLE);
+ apiTestScenarioMenu.setIcon("fa fa-folder");
+ apiTestScenarioMenu.setName("API测试场景");
+ apiTestScenarioMenu.setCode("$API-TestScenario");
+ menus.add(apiTestScenarioMenu);
+
+ MetaMenu apiStepMenu = MetaMenu.createEruptClassMenu(
+ ApiStep
+ .class,
+ menus.get(0), 5, MenuTypeEnum.TABLE);
+ apiStepMenu.setIcon("fa fa-folder");
+ apiStepMenu.setName("API用例步骤");
+ apiStepMenu.setCode("$API-Step");
+ menus.add(apiStepMenu);
+// MetaMenu apiDefMenu = MetaMenu.createSimpleMenu("$API-def", "接口定义", "fa fa-check-square-o",
+// menus.get(0), 1, "");
+// menus.add(apiDefMenu);
+// addNewMenu(
+// menus,"$API-Spec-Git","API定义仓库", "fa fa-meetup", ApiSpecGitRepoModel.class,
+// MenuTypeEnum.TABLE,1,0
+// );
+// addNewMenu(
+// menus,"$API-Spec","API最新版本", "fa fa-gitlab", ApiSpecVersionModel.class,
+// MenuTypeEnum.TABLE,1,1
+// );
+
+ return menus;
+ }
+
+
+ static {
+ EruptModuleInvoke.addEruptModule(FluentQAApiModule.class);
+ }
+
+ @Override
+ public void initFun() {
+ EruptModule.super.initFun();
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/FluentUploadTCModule.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/FluentUploadTCModule.java
new file mode 100644
index 0000000..70d4748
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/FluentUploadTCModule.java
@@ -0,0 +1,53 @@
+package io.fluent.qtm;
+
+import io.fluent.qtm.upload.model.UploadFileModel;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import xyz.erupt.core.annotation.EruptScan;
+import xyz.erupt.core.constant.MenuTypeEnum;
+import xyz.erupt.core.module.EruptModule;
+import xyz.erupt.core.module.EruptModuleInvoke;
+import xyz.erupt.core.module.MetaMenu;
+import xyz.erupt.core.module.ModuleInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+@ComponentScan
+@EntityScan
+@EruptScan
+@EnableConfigurationProperties
+public class FluentUploadTCModule implements EruptModule {
+
+ public FluentUploadTCModule() {
+ }
+
+ @Override
+ public ModuleInfo info() {
+ return ModuleInfo.builder().name("fluent-tc-sync").build();
+ }
+
+ @Override
+ public void run() {
+ EruptModule.super.run();
+ }
+
+ @Override
+ public List initMenus() {
+ List menus = new ArrayList<>();
+ menus.add(MetaMenu.createRootMenu("$tc-upload", "测试文件管理", "fa fa-file", 100));
+ MetaMenu tfUploadSyncMenu = MetaMenu.createEruptClassMenu(UploadFileModel.class, menus.get(0), 0, MenuTypeEnum.TABLE);
+ tfUploadSyncMenu.setIcon("fa fa-folder-open");
+ tfUploadSyncMenu.setName("测试文件同步");
+ tfUploadSyncMenu.setCode("$tc-upload-sync");
+ menus.add(tfUploadSyncMenu);
+ return menus;
+ }
+
+ static {
+ EruptModuleInvoke.addEruptModule(FluentUploadTCModule.class);
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateApiCaseByCaptureDataHandler.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateApiCaseByCaptureDataHandler.java
new file mode 100644
index 0000000..1466ab1
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateApiCaseByCaptureDataHandler.java
@@ -0,0 +1,24 @@
+package io.fluent.qtm.api.handler;
+
+import io.fluent.qtm.api.model.ApiMonitorRecord;
+import io.fluent.qtm.api.service.ApiTestCaseService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import xyz.erupt.annotation.fun.OperationHandler;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Service
+@Slf4j
+public class GenerateApiCaseByCaptureDataHandler implements OperationHandler {
+
+ @Resource
+ private ApiTestCaseService apiService;
+ @Override
+ public String exec(List data, Void unused, String[] param) {
+ log.info("start convert api capture data");
+ apiService.convertApiMonitorRecordToTestCase(data);
+ return null;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateApiTestStepByApiTestRecord.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateApiTestStepByApiTestRecord.java
new file mode 100644
index 0000000..02361bd
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateApiTestStepByApiTestRecord.java
@@ -0,0 +1,24 @@
+package io.fluent.qtm.api.handler;
+
+import io.fluent.qtm.api.model.ApiTestRecord;
+import io.fluent.qtm.api.service.ApiTestCaseService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import xyz.erupt.annotation.fun.OperationHandler;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Service
+@Slf4j
+public class GenerateApiTestStepByApiTestRecord implements OperationHandler {
+
+ @Resource
+ private ApiTestCaseService apiService;
+ @Override
+ public String exec(List data, Void unused, String[] param) {
+ log.info("start convert api capture data");
+ apiService.convertApiTestResultToApiTestStep(data);
+ return null;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateRawApiCaseHandler.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateRawApiCaseHandler.java
new file mode 100644
index 0000000..bd98597
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/handler/GenerateRawApiCaseHandler.java
@@ -0,0 +1,22 @@
+package io.fluent.qtm.api.handler;
+
+import io.fluent.qtm.api.model.RemoteApi;
+import io.fluent.qtm.api.service.ApiTestCaseService;
+import org.springframework.stereotype.Service;
+import xyz.erupt.annotation.fun.OperationHandler;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Service
+public class GenerateRawApiCaseHandler implements OperationHandler {
+
+ @Resource
+ private ApiTestCaseService apiService;
+ @Override
+ public String exec(List data, Void unused, String[] param) {
+ System.out.println("this is tests");
+ apiService.convertToRawTestCase(data);
+ return null;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiMonitorRecord.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiMonitorRecord.java
new file mode 100644
index 0000000..cc2999e
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiMonitorRecord.java
@@ -0,0 +1,131 @@
+package io.fluent.qtm.api.model;
+
+
+import io.fluent.qtm.api.handler.GenerateApiCaseByCaptureDataHandler;
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_erupt.RowOperation;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.ViewType;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.annotation.sub_field.sub_edit.TagsType;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "api_monitor_record")
+@Erupt(
+ name = "接口访问记录",
+ layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30),
+ power = @Power(importable = true, export = true),
+ rowOperation = {@RowOperation(
+ title = "生成接口用例数据",
+ operationHandler = GenerateApiCaseByCaptureDataHandler.class)},
+ orderBy = "ApiMonitorRecord.id desc"
+
+)
+@Data
+public class ApiMonitorRecord extends MetaModel {
+
+ @EruptField(
+ views = @View(title = "app"),
+ edit = @Edit(
+ title = "app应用名",
+ type = EditType.TAGS, search = @Search(vague = true), notNull = true,
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct app from api_monitor_record"
+ )
+ ))
+ private String app;
+ @EruptField(
+ views = @View(title = "录制名称"),
+ edit = @Edit(title = "录制名称", notNull = true, search = @Search)
+ )
+ private String recordName;
+ @EruptField(
+ views = @View(title = "请求地址"),
+ edit = @Edit(title = "请求地址", notNull = true, search = @Search)
+ )
+ private String requestUrl;
+
+ @EruptField(
+ views = @View(title = "服务"),
+ edit = @Edit(
+ title = "服务",
+ type = EditType.TAGS, search = @Search(vague = true), notNull = true,
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct service from api_monitor_record"
+ )
+ )
+ )
+
+ private String service;
+ @EruptField(
+ views = @View(title = "接口名称"),
+ edit = @Edit(title = "接口名称", notNull = true, search = @Search)
+ )
+ private String api;
+
+ @EruptField(
+ views = @View(title = "服务URL"),
+ edit = @Edit(title = "服务URL", notNull = true, search = @Search)
+ )
+ private String path;
+
+ @EruptField(
+ views = @View(title = "请求头"),
+ edit = @Edit(title = "请求报文", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String requestHeaders;
+
+ @EruptField(
+ views = @View(title = "HTTP方法"),
+ edit = @Edit(title = "HTTP方法", notNull = true, search = @Search)
+ )
+ private String method;
+
+ @EruptField(
+ views = @View(title = "请求报文", type = ViewType.CODE),
+ edit = @Edit(title = "请求报文", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String requestBody;
+
+
+ @EruptField(
+ views = @View(title = "response_headers"),
+ edit = @Edit(title = "responseHeaders", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String responseHeaders;
+
+ @EruptField(
+ views = @View(title = "status_code"),
+ edit = @Edit(title = "status_code", notNull = true, search = @Search)
+ )
+ private int statusCode;
+
+ @EruptField(
+ views = @View(title = "返回报文", type = ViewType.CODE),
+ edit = @Edit(title = "返回报文", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String responseBody;
+
+
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecChangeModel.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecChangeModel.java
new file mode 100644
index 0000000..723930d
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecChangeModel.java
@@ -0,0 +1,52 @@
+package io.fluent.qtm.api.model;
+
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.jpa.model.BaseModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "api_spec_change")
+@Erupt(
+ layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30),
+ name = "api spec 变化记录", power = @Power(export = true)
+)
+@Data
+public class ApiSpecChangeModel extends BaseModel {
+ @EruptField(
+ views = @View(title = "应用名-appName")
+ )
+ private String name;
+ @EruptField(
+ views = @View(title = "GIT URL")
+ )
+ private String gitUrl;
+ @EruptField(
+ views = @View(title = "GIT分支")
+ )
+ private String branch;
+
+ @EruptField(
+ views = @View(title = "创建时间")
+ )
+ private LocalDateTime createdTime;
+
+ @EruptField(
+ views = @View(title = "appVersion")
+ )
+ private String appVersion;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecGitRepoModel.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecGitRepoModel.java
new file mode 100644
index 0000000..cb97dfd
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecGitRepoModel.java
@@ -0,0 +1,47 @@
+package io.fluent.qtm.api.model;
+
+import lombok.Data;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "apispec_git_repo")
+@Data
+@Erupt(name = "skel仓库设置", layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30),
+ power = @Power(importable = true, export = true))
+public class ApiSpecGitRepoModel extends MetaModel {
+ @EruptField(
+ views = @View(title = "应用名-appName"),
+ edit = @Edit(title = "应用名-App Name", notNull = true, search = @Search)
+ )
+ private String name;
+ @EruptField(
+ views = @View(title = "gitUrl"),
+ edit = @Edit(title = "gitUrl", notNull = true)
+ )
+ private String gitUrl;
+
+ @EruptField(
+ views = @View(title = "gitlabId"),
+ edit = @Edit(title = "gitlabId", notNull = true)
+ )
+ private Integer gitlabId;
+
+ @EruptField(
+ views = @View(title = "webUrl"),
+ edit = @Edit(title = "webUrl", notNull = true)
+ )
+ private String webUrl;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecVersionModel.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecVersionModel.java
new file mode 100644
index 0000000..6bd226d
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiSpecVersionModel.java
@@ -0,0 +1,102 @@
+package io.fluent.qtm.api.model;
+
+import io.fluent.base.model.ModelWithValidFlagVo;
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Where;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.ViewType;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.InputType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "api_spec_version")
+@Erupt(
+ name = "远程服务原始文件",
+ power = @Power(export = true),
+ layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30)
+)
+@Data
+@SQLDelete(sql = "update api_spec_version set valid=false where id=?")
+@Where(clause = "valid = true")
+public class ApiSpecVersionModel extends ModelWithValidFlagVo {
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String name;
+
+
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String type="POSTMAN";
+
+ @EruptField(
+ views = @View(
+ title = "服务类型"
+ ),
+ edit = @Edit(
+ title = "服务类型",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String serviceType; //API or RPC
+
+ @EruptField(
+ views = @View(
+ title = "版本"
+ ),
+ edit = @Edit(
+ title = "版本",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String appVersion;
+
+ @EruptField(
+ views = @View(title = "GIT URL")
+ )
+ private String gitUrl;
+ @EruptField(
+ views = @View(title = "GIT分支")
+ )
+ private String branch;
+
+ @EruptField(
+ views = @View(title = "接口定义", type = ViewType.CODE),
+ edit = @Edit(title = "接口定义", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String spec;
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiStep.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiStep.java
new file mode 100644
index 0000000..9f26690
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiStep.java
@@ -0,0 +1,156 @@
+package io.fluent.qtm.api.model;
+
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.annotation.sub_field.sub_edit.TagsType;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "api_steps")
+@Erupt(
+ name = "接口测试用例", layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30), power = @Power(importable = true, export = true),
+ orderBy = "ApiTestStep.updateTime desc"
+)
+public class ApiStep extends MetaModel{
+
+ @EruptField(
+ views = @View(title = "场景"),
+ edit = @Edit(title = "场景", notNull = true, search = @Search)
+ )
+ private String scenario;
+
+ @EruptField(
+ views = @View(title = "用例名称"),
+ edit = @Edit(title = "用例名称", notNull = true, search = @Search)
+ )
+ private String caseName;
+
+ @EruptField(
+ views = @View(title = "服务"),
+ edit = @Edit(
+ search = @Search,
+ title = "获取可选服务",
+ type = EditType.TAGS,
+ desc = "获取可选服务",
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct service_name from remote_services where type='API' and valid=true"
+ ))
+ )
+ private String serviceName;
+ @EruptField(
+ views = @View(title = "服务方法"),
+ edit = @Edit(title = "服务方法", notNull = true, search = @Search)
+ )
+ private String serviceMethod;
+
+ @EruptField(
+ views = @View(title = "接口路径"),
+ edit = @Edit(title = "接口路径", notNull = true, search = @Search)
+ )
+ private String path;
+
+ @EruptField(
+// views = @View(title = "测试请求", type = ViewType.CODE),
+ edit = @Edit(title = "测试请求", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String request;
+ @EruptField(
+// views = @View(title = "接口请求结果"),
+ edit = @Edit(title = "接口请求结果",
+ type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String result;
+
+
+ @EruptField(
+// views = @View(title = "预期结果"),
+ edit = @Edit(title = "预期结果", notNull = true, type = EditType.CODE_EDITOR,
+ codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String expect;
+
+
+ public String getScenario() {
+ return scenario;
+ }
+
+ public void setScenario(String scenario) {
+ this.scenario = scenario;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public String getServiceMethod() {
+ return serviceMethod;
+ }
+
+ public void setServiceMethod(String serviceMethod) {
+ this.serviceMethod = serviceMethod;
+ }
+
+ public String getCaseName() {
+ return caseName;
+ }
+
+ public void setCaseName(String caseName) {
+ this.caseName = caseName;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getRequest() {
+ return request;
+ }
+
+ public void setRequest(String request) {
+ this.request = request;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+
+
+ public String getExpect() {
+ return expect;
+ }
+
+ public void setExpect(String expect) {
+ this.expect = expect;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiTestRecord.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiTestRecord.java
new file mode 100644
index 0000000..e03248c
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiTestRecord.java
@@ -0,0 +1,131 @@
+package io.fluent.qtm.api.model;
+
+import io.fluent.qtm.api.handler.GenerateApiTestStepByApiTestRecord;
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_erupt.RowOperation;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.annotation.sub_field.sub_edit.TagsType;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * 1. 原先的表结构设计几个问题:
+ * - 没有办法区分那次测试运行记录
+ * - 查找不太方便
+ * - name 和service name 重复,没有必要同时使用
+ * - serviceName 从remote service里面取不过滤API,不够精确
+ * 修改方式:
+ * - name 修改为测试用例运行名称
+ * - serviceName 取tags 从remote service 的API 中取
+ */
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "api_test_record")
+@Erupt(
+ name = "接口测试结果", layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30), power = @Power(importable = true, export = true),
+ orderBy = "ApiTestRecord.id desc",
+ rowOperation = {@RowOperation(
+ title = "生成可用测试步骤",
+ operationHandler = GenerateApiTestStepByApiTestRecord.class)}
+)
+@Data
+public class ApiTestRecord extends MetaModel {
+ @EruptField(
+ views = @View(title = "测试运行名称"),
+ edit = @Edit(title = "name", search = @Search)
+ )
+ private String name;
+
+ @EruptField(
+ views = @View(title = "场景"),
+ edit = @Edit(title = "场景", notNull = true, search = @Search)
+ )
+ private String scenario;
+
+ @EruptField(
+ views = @View(title = "用例名称"),
+ edit = @Edit(title = "用例名称", notNull = true, search = @Search)
+ )
+ private String caseName;
+
+ @EruptField(
+ views = @View(title = "服务"),
+ edit = @Edit(
+ search = @Search,
+ title = "获取可选服务",
+ type = EditType.TAGS,
+ desc = "获取可选服务",
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct service_name from remote_services where type='API' and valid=true"
+ ))
+ )
+ private String serviceName;
+ @EruptField(
+ views = @View(title = "服务方法"),
+ edit = @Edit(title = "服务方法", notNull = true, search = @Search)
+ )
+ private String serviceMethod;
+
+ @EruptField(
+ views = @View(title = "接口路径"),
+ edit = @Edit(title = "接口路径", notNull = true, search = @Search)
+ )
+ private String path;
+
+ @EruptField(
+// views = @View(title = "测试请求", type = ViewType.CODE),
+ edit = @Edit(title = "测试请求", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String request;
+ @EruptField(
+// views = @View(title = "接口请求结果"),
+ edit = @Edit(title = "接口请求结果",
+ type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String result;
+
+ @EruptField(
+ views = @View(title = "状态码"),
+ edit = @Edit(title = "状态码", notNull = true, search = @Search)
+ )
+ private String statusCode;
+
+ @EruptField(
+ views = @View(title = "错误日志"),
+ edit = @Edit(title = "错误日志",
+ type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String errorLog;
+
+ @EruptField(
+// views = @View(title = "预期结果"),
+ edit = @Edit(title = "预期结果", notNull = true, type = EditType.CODE_EDITOR,
+ codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String expect;
+
+ //TODO: 通过或者失败
+ @EruptField(
+ views = @View(title = "用例执行结果"),
+ edit = @Edit(title = "用例执行结果", search = @Search)
+ )
+ private boolean isSuccess;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiTestScenario.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiTestScenario.java
new file mode 100644
index 0000000..eb187f8
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/ApiTestScenario.java
@@ -0,0 +1,157 @@
+package io.fluent.qtm.api.model;
+
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlag;
+import io.fluent.base.product.model.ProductModuleModel;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.LinkTree;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.annotation.sub_field.sub_edit.TagsType;
+
+import javax.persistence.*;
+import java.util.Set;
+
+/**
+ *
+ */
+@Entity
+@Erupt(name = "接口测试用例",
+ power = @Power(export = true),
+ orderBy = "ApiTestScenario.updateTime desc",
+ linkTree = @LinkTree(field = "module"),
+ layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30))
+@Table(name = "api_test_scenario")
+public class ApiTestScenario extends ModelWithValidFlag {
+
+ @ManyToOne
+ @JoinColumn(name = "product_id")
+ @EruptField(
+ views = @View(title = "所属模块", column = "details"),
+ edit = @Edit(
+ notNull = true,
+ search = @Search,
+ title = "产品模块选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ pid = "parent.id"))
+ )
+ private ProductModuleModel module;
+
+
+ @EruptField(
+ views = @View(
+ title = "测试场景"
+ ),
+ edit = @Edit(
+ title = "测试场景",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String testScenario;
+
+ @EruptField(
+ views = @View(
+ title = "测试场景详细描述"
+ ),
+ edit = @Edit(
+ title = "测试场景详细描述",
+ type = EditType.TEXTAREA, search = @Search, notNull = true
+ )
+ )
+ private String details;
+
+ @EruptField(
+ views = @View(
+ title = "优先级"
+ ),
+ edit = @Edit(
+ title = "优先级",
+ type = EditType.TAGS,
+ search = @Search,
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct key,detail from master_data where category_code = 'PRIORITY' order by 1 "
+ )
+ )
+ )
+ private String priority = "P2";
+
+ @EruptField(
+ views = @View(title = "场景参数"),
+ edit = @Edit(title = "场景参数",
+ type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String scenarioParameters;
+
+ @JoinTable(name = "api_test_scenario_steps",
+ joinColumns = @JoinColumn(name = "api_test_scenario_id", referencedColumnName = "id"),
+ inverseJoinColumns = @JoinColumn(name = "api_test_step_id", referencedColumnName = "id"))
+ @ManyToMany(fetch = FetchType.EAGER)
+ @EruptField(
+ views = @View(title = "包含用例"),
+ edit = @Edit(
+ title = "包含用例",
+ type = EditType.TAB_TABLE_REFER
+ )
+ )
+ private Set testSteps;
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+
+ public ProductModuleModel getModule() {
+ return module;
+ }
+
+ public void setModule(ProductModuleModel module) {
+ this.module = module;
+ }
+
+ public String getTestScenario() {
+ return testScenario;
+ }
+
+ public void setTestScenario(String testScenario) {
+ this.testScenario = testScenario;
+ }
+
+ public String getDetails() {
+ return details;
+ }
+
+ public void setDetails(String details) {
+ this.details = details;
+ }
+
+ public String getScenarioParameters() {
+ return scenarioParameters;
+ }
+
+ public void setScenarioParameters(String scenarioParameters) {
+ this.scenarioParameters = scenarioParameters;
+ }
+
+ public Set getTestSteps() {
+ return testSteps;
+ }
+
+ public void setTestSteps(Set testSteps) {
+ this.testSteps = testSteps;
+ }
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RawApiTestCase.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RawApiTestCase.java
new file mode 100644
index 0000000..9498f09
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RawApiTestCase.java
@@ -0,0 +1,96 @@
+package io.fluent.qtm.api.model;
+
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.ViewType;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "raw_api_cases")
+@Erupt(
+ name = "接口测试用例生成", layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30), power = @Power(importable = true, export = true),
+ orderBy = "RawApiTestCase.createTime "
+)
+@Data
+public class RawApiTestCase extends MetaModel{
+ @EruptField(
+ views = @View(title = "测试场景"),
+ edit = @Edit(title = "测试场景", search = @Search)
+ )
+ private String scenario;
+
+ @EruptField(
+ views = @View(title = "服务名称"),
+ edit = @Edit(title = "服务名称", notNull = true, search = @Search)
+ )
+ private String serviceName;
+
+ @EruptField(
+ views = @View(title = "API接口"),
+ edit = @Edit(title = "API接口", notNull = true, search = @Search)
+ )
+ private String serviceMethod;
+
+ @EruptField(
+ views = @View(title = "用例名称"),
+ edit = @Edit(title = "用例名称", notNull = true, search = @Search)
+ )
+ private String name;
+
+ @EruptField(
+ views = @View(title = "请求路径"),
+ edit = @Edit(title = "请求路径", notNull = true, search = @Search)
+ )
+ private String uri;
+
+ @EruptField(
+ views = @View(title = "请求方法"),
+ edit = @Edit(title = "请求方法", notNull = true)
+ )
+ private String method = "POST";
+
+ @EruptField(
+ views = @View(title = "输入", type = ViewType.CODE),
+ edit = @Edit(title = "输入",
+ type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String input;
+
+ @EruptField(
+ views = @View(title = "期望结果", type = ViewType.CODE),
+ edit = @Edit(title = "期望结果", type = EditType.CODE_EDITOR,
+ codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String expected;
+
+ @EruptField(
+ views = @View(title = "优先级"),
+ edit = @Edit(title = "优先级")
+ )
+ private String priority = "P1";
+
+ @EruptField(
+ views = @View(title = "是否运行"),
+ edit = @Edit(title = "是否运行")
+ )
+ private boolean isRun = true;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApi.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApi.java
new file mode 100644
index 0000000..84763bd
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApi.java
@@ -0,0 +1,275 @@
+package io.fluent.qtm.api.model;
+
+import cn.hutool.core.lang.UUID;
+import io.fluent.qtm.api.handler.GenerateRawApiCaseHandler;
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlag;
+import lombok.Data;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Where;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_erupt.RowOperation;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.ViewType;
+import xyz.erupt.annotation.sub_field.sub_edit.*;
+import xyz.erupt.toolkit.handler.SqlChoiceFetchHandler;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@DynamicUpdate
+@DynamicInsert
+@Entity
+@Table(name = "remote_services")
+@Erupt(
+ name = "远程服务清单", layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30),
+ power = @Power(export = true),
+ rowOperation = {@RowOperation(
+ title = "生成原始接口用例",
+ operationHandler = GenerateRawApiCaseHandler.class)}
+)
+@Data
+@SQLDelete(sql = "update remote_services set valid=false where id=?")
+@Where(clause = "valid = true")
+public class RemoteApi extends ModelWithValidFlag {
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String name;
+
+ @EruptField(
+ views = @View(
+ title = "产品"
+ ),
+ edit = @Edit(
+ title = "产品",
+ type = EditType.CHOICE,
+ desc = "获取产品",
+ choiceType = @ChoiceType(
+ fetchHandler = SqlChoiceFetchHandler.class,
+ fetchHandlerParams = "select id,name,details from products where valid =true and parent_id is NULL"
+ ))
+ )
+ private Long productId;
+
+ @EruptField(
+ views = @View(title = "模块名"),
+ edit = @Edit(
+ search = @Search,
+ title = "获取可选模块",
+ type = EditType.TAGS,
+ desc = "动态获取可选模块",
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct module_name from remote_services where valid=true"
+ ))
+ )
+ private String moduleName;
+
+ @EruptField(
+ views = @View(title = "服务"),
+ edit = @Edit(
+ search = @Search,
+ title = "获取可选服务",
+ type = EditType.TAGS,
+ desc = "获取可选服务",
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct service_name from remote_services where valid=true"
+ ))
+ )
+ private String serviceName;
+
+ @EruptField(
+ views = @View(title = "地址"),
+ edit = @Edit(title = "地址", notNull = true)
+ )
+ private String endpoint;
+
+ @EruptField(
+ views = @View(title = "方法"),
+ edit = @Edit(title = "方法", notNull = true, search = @Search)
+ )
+ private String serviceMethod;
+
+ @EruptField(
+ views = @View(title = "http请求方法"),
+ edit = @Edit(title = "http请求方法", notNull = true)
+ )
+ private String httpMethod;
+
+ @EruptField(
+ views = @View(title = "请求报文", type = ViewType.CODE),
+ edit = @Edit(title = "请求报文", type = EditType.CODE_EDITOR, codeEditType = @CodeEditorType(language = "json"))
+ )
+ private String body;
+
+ @EruptField(
+ views = @View(title = "接口类型"),
+ edit = @Edit(title = "接口类型", search = @Search,
+ type = EditType.CHOICE, choiceType = @ChoiceType(
+ vl = {@VL(value = "API", label = "API"), @VL(value = "RPC", label = "RPC")}
+ ))
+ )
+ private String type;
+
+ @EruptField(
+ views = @View(title = "服务使用状态"),
+ edit = @Edit(title = "服务使用状态",
+ search = @Search, notNull = true,
+ type = EditType.CHOICE, choiceType = @ChoiceType(
+ vl = {@VL(value = "NEW", label = "新增"),
+ @VL(value = "IN_USE", label = "使用中"),
+ @VL(value = "UPDATE", label = "更新"),
+ @VL(value = "END_OF_LIFE", label = "已作废"),})))
+ private String status;
+
+ @EruptField(
+ views = @View(
+ title = "引入时版本"
+ ),
+ edit = @Edit(
+ title = "引入时版本",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String addedVersion;
+
+ @EruptField(
+ views = @View(
+ title = "最新版本"
+ ),
+ edit = @Edit(
+ title = "最新版本",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String latestVersion;
+
+ @EruptField(
+ views = @View(show = false, title = "uid")
+ )
+ private String uId = UUID.fastUUID().toString();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Long getProductId() {
+ return productId;
+ }
+
+ public void setProductId(Long productId) {
+ this.productId = productId;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+
+ public void setModuleName(String moduleName) {
+ this.moduleName = moduleName;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public String getServiceMethod() {
+ return serviceMethod;
+ }
+
+ public void setServiceMethod(String serviceMethod) {
+ this.serviceMethod = serviceMethod;
+ }
+
+ public String getHttpMethod() {
+ return httpMethod;
+ }
+
+ public void setHttpMethod(String httpMethod) {
+ this.httpMethod = httpMethod;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getAddedVersion() {
+ return addedVersion;
+ }
+
+ public void setAddedVersion(String addedVersion) {
+ this.addedVersion = addedVersion;
+ }
+
+ public String getLatestVersion() {
+ return latestVersion;
+ }
+
+ public void setLatestVersion(String latestVersion) {
+ this.latestVersion = latestVersion;
+ }
+
+ public String getuId() {
+ return uId;
+ }
+
+ public void setuId(String uId) {
+ this.uId = uId;
+ }
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApiStatus.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApiStatus.java
new file mode 100644
index 0000000..4b66a5c
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApiStatus.java
@@ -0,0 +1,5 @@
+package io.fluent.qtm.api.model;
+
+public enum RemoteApiStatus {
+ NEW,IN_USE,UPDATED,END_OF_LIFE
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApiType.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApiType.java
new file mode 100644
index 0000000..74c2557
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/model/RemoteApiType.java
@@ -0,0 +1,5 @@
+package io.fluent.qtm.api.model;
+
+public enum RemoteApiType {
+ API,RPC
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/package-info.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/package-info.java
new file mode 100644
index 0000000..73f4e8e
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/package-info.java
@@ -0,0 +1 @@
+package io.fluent.qtm.api;
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiMonitorRecordRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiMonitorRecordRepo.java
new file mode 100644
index 0000000..e03552b
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiMonitorRecordRepo.java
@@ -0,0 +1,14 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.ApiMonitorRecord;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface ApiMonitorRecordRepo extends JpaRepository, JpaSpecificationExecutor {
+
+ List findApiMonitorRecordByPath(String path);
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecChangeRepository.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecChangeRepository.java
new file mode 100644
index 0000000..ff3cdf3
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecChangeRepository.java
@@ -0,0 +1,11 @@
+package io.fluent.qtm.api.repo;
+
+
+import io.fluent.qtm.api.model.ApiSpecChangeModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ApiSpecChangeRepository extends JpaRepository {
+
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecGitRepoRepository.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecGitRepoRepository.java
new file mode 100644
index 0000000..4a6af7a
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecGitRepoRepository.java
@@ -0,0 +1,10 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.ApiSpecGitRepoModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ApiSpecGitRepoRepository extends JpaRepository {
+
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecVersionRepository.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecVersionRepository.java
new file mode 100644
index 0000000..361f79d
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiSpecVersionRepository.java
@@ -0,0 +1,10 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.ApiSpecVersionModel;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ApiSpecVersionRepository extends JpaRepository {
+
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiTestScenarioRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiTestScenarioRepo.java
new file mode 100644
index 0000000..e389772
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiTestScenarioRepo.java
@@ -0,0 +1,10 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.ApiTestScenario;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ApiTestScenarioRepo extends JpaRepository, JpaSpecificationExecutor {
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiTestStepRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiTestStepRepo.java
new file mode 100644
index 0000000..f867291
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/ApiTestStepRepo.java
@@ -0,0 +1,10 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.ApiStep;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ApiTestStepRepo extends JpaRepository, JpaSpecificationExecutor {
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/RawApiTestCaseRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/RawApiTestCaseRepo.java
new file mode 100644
index 0000000..fb9e408
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/RawApiTestCaseRepo.java
@@ -0,0 +1,10 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.RawApiTestCase;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface RawApiTestCaseRepo extends JpaRepository, JpaSpecificationExecutor {
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/RemoteServiceRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/RemoteServiceRepo.java
new file mode 100644
index 0000000..f6f4ad0
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/repo/RemoteServiceRepo.java
@@ -0,0 +1,23 @@
+package io.fluent.qtm.api.repo;
+
+import io.fluent.qtm.api.model.RemoteApi;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface RemoteServiceRepo extends JpaRepository, JpaSpecificationExecutor {
+
+ Optional findRemoteApiByEndpointAndServiceNameAndServiceMethod(
+ String endpoint,String serviceName,String serviceMethod
+ );
+
+ Optional> findRemoteApiByModuleNameAndServiceNameAndLatestVersionNot(
+ String moduleName,String serviceName,String latestVersion
+ );
+
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/service/ApiTestCaseService.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/service/ApiTestCaseService.java
new file mode 100644
index 0000000..cd465be
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/service/ApiTestCaseService.java
@@ -0,0 +1,107 @@
+package io.fluent.qtm.api.service;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import io.fluent.builtin.CollectionsUtils;
+import io.fluent.qtm.api.model.*;
+import io.fluent.qtm.api.repo.ApiMonitorRecordRepo;
+import io.fluent.qtm.api.repo.ApiTestStepRepo;
+import io.fluent.qtm.api.repo.RawApiTestCaseRepo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+@Service
+public class ApiTestCaseService {
+ private final String DEFAULT_EXPECTED = "{ \"status_code\":200,\"values\":{}\n" +
+ "}";
+ @Resource
+ RawApiTestCaseRepo rawApiTestCaseRepo;
+
+ @Resource
+ ApiMonitorRecordRepo apiMonitorRecordRepo;
+
+ @Resource
+ ApiTestStepRepo apiTestStepRepo;
+
+
+ /**
+ * @param services: HTTP API Services
+ * 1. Merge All HttpAPI Services if method,service and request-body/input is same
+ */
+ public void convertToRawTestCase(List services) {
+ List cases = new ArrayList<>();
+ services.forEach(service -> {
+ RawApiTestCase apiCase = new RawApiTestCase();
+ BeanUtils.copyProperties(service, apiCase);
+ apiCase.setUri(service.getEndpoint());
+ apiCase.setExpected(DEFAULT_EXPECTED);
+ //get body
+ String path = service.getEndpoint().replaceAll("https://\\{\\{base_url\\}\\}", "");
+ List result = apiMonitorRecordRepo.findApiMonitorRecordByPath(path);
+ if (!result.isEmpty()) {
+ apiCase.setInput(result.get(0).getRequestBody());
+ } else {
+ apiCase.setInput(service.getBody());
+ }
+ cases.add(apiCase);
+ });
+ rawApiTestCaseRepo.saveAll(cases);
+ }
+
+ /**
+ * @param records Http traffic
+ * 1. Merge All HttpAPI Services if method,service and request-body/input is same
+ */
+ public void convertApiMonitorRecordToTestCase(List records) {
+ List cases = new ArrayList<>();
+ List result = CollectionsUtils.filterToReduceRedundant(
+ records, new Function() {
+ @Override
+ public String apply(ApiMonitorRecord apiMonitorRecord) {
+ return StrUtil.join(
+ "-", apiMonitorRecord.getApi(), apiMonitorRecord.getApp(),
+ apiMonitorRecord.getService(), apiMonitorRecord.getPath(),
+ apiMonitorRecord.getMethod(), apiMonitorRecord.getRequestBody()
+ );
+ }
+ }
+ );
+ result.forEach(service -> {
+ RawApiTestCase apiCase = new RawApiTestCase();
+ BeanUtils.copyProperties(service, apiCase);
+ apiCase.setUri(service.getPath());
+ apiCase.setExpected(DEFAULT_EXPECTED);
+ apiCase.setServiceMethod(service.getMethod());
+ apiCase.setServiceName(service.getService());
+ apiCase.setName(service.getService());
+ apiCase.setServiceMethod(service.getApi());
+ //get body
+ apiCase.setInput(service.getRequestBody());
+ apiCase.setScenario(service.getRecordName());
+ cases.add(apiCase);
+ });
+ rawApiTestCaseRepo.saveAll(cases);
+ }
+
+ /**
+ * Only Passed Test Scenario could be converted into test steps
+ *
+ * @param data
+ */
+ public void convertApiTestResultToApiTestStep(List data) {
+ List apiTestSteps = new ArrayList<>();
+ data.forEach((apiTestRecord) -> {
+ if (apiTestRecord.isSuccess()) {
+ apiTestSteps.add(BeanUtil.copyProperties(apiTestRecord, ApiStep.class));
+ } else {
+ throw new RuntimeException("some cases are failed, can't convert to api test step");
+ }
+ });
+ apiTestStepRepo.saveAll(apiTestSteps);
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/service/RemoteApiService.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/service/RemoteApiService.java
new file mode 100644
index 0000000..27c3803
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/api/service/RemoteApiService.java
@@ -0,0 +1,142 @@
+package io.fluent.qtm.api.service;
+
+import cn.hutool.core.bean.BeanUtil;
+import io.fluent.postman.PostmanParser;
+import io.fluent.postman.model.PostmanCollection;
+import io.fluent.postman.model.PostmanItem;
+import io.fluent.qtm.api.model.ApiSpecVersionModel;
+import io.fluent.qtm.api.model.RemoteApi;
+import io.fluent.qtm.api.model.RemoteApiStatus;
+import io.fluent.qtm.api.repo.RemoteServiceRepo;
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.base.product.service.ProductModuleService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Slf4j
+public class RemoteApiService {
+
+ @Autowired
+ private ProductModuleService productMetaService;
+
+ @Autowired
+ private RemoteServiceRepo remoteServiceRepo;
+
+
+ /**
+ * 1. 解析postman 文件
+ * 2. 确认接口是
+ * - 新增:NEW: 当前记录无记录,则更新
+ * - 更新:UPDATED: 当前记录中有记录,但是接口定义发生变化,比如请求内容
+ * - 使用中,IN_USE:
+ * - 移除:END_OF_LIFE: 接口不在最新清单中
+ * 3.
+ *
+ * @param apiSpec
+ */
+ @Transactional
+ public void apiSpecToApiList(ApiSpecVersionModel apiSpec, String updater) {
+ ProductModuleModel productMeta = productMetaService.createApiModuleIfNotExist(apiSpec.getName(), updater);
+ if (apiSpec.getSpec().isEmpty()) return;
+ PostmanCollection collection = PostmanParser.create().toPostmanCollection(apiSpec.getSpec());
+ for (PostmanItem postmanItem : collection.getItem()) {
+ for (PostmanItem item : postmanItem.getItem()) {
+ RemoteApi rs = toRemoteApi(apiSpec, productMeta, postmanItem, item);
+ createOrUpdateRemoteApi(rs, apiSpec);
+ }
+ updateStatusToEndOfLife(apiSpec, postmanItem);
+ }
+ }
+
+ @Transactional
+ public void apiSpecsToApiList(List apiSpecs, String updater) {
+ for (ApiSpecVersionModel apiSpec : apiSpecs) {
+ try {
+ this.apiSpecToApiList(apiSpec, updater);
+ } catch (Exception e) {
+ log.error("%s-api-failed,error=%s".formatted(
+ apiSpec.getName(), e.getMessage()
+ ));
+ }
+ }
+ }
+
+ private RemoteApi toRemoteApi(ApiSpecVersionModel apiSpec, ProductModuleModel productMeta,
+ PostmanItem postmanItem, PostmanItem item) {
+ RemoteApi rs = new RemoteApi();
+ rs.setName(item.getName());
+ rs.setServiceName(postmanItem.getName());
+ rs.setServiceMethod(item.getName());
+ rs.setBody(item.getRequest().getBody().get("raw").toString());
+ rs.setHttpMethod(item.getRequest().getMethod());
+ rs.setEndpoint(item.getRequest().getUrl().getRaw());
+ rs.setType(apiSpec.getServiceType());
+ rs.setModuleName(apiSpec.getName());
+ rs.setProductId(productMeta.getParent().getId());
+ return rs;
+ }
+
+ /**
+ * create or update 基本可以使用同一种方式处理
+ * 1. 输入实体
+ * 2. 字段检验规则
+ * 3. 判断重复确认条件
+ * 4. 更新字段处理,保存记录
+ * TODO: try to integrate with Feishu
+ *
+ * @param newApi
+ */
+ public void createOrUpdateRemoteApi(RemoteApi newApi, ApiSpecVersionModel apiSpec) {
+ Optional api = remoteServiceRepo.findRemoteApiByEndpointAndServiceNameAndServiceMethod(
+ newApi.getEndpoint(),
+ newApi.getServiceName(),
+ newApi.getServiceMethod());
+ if (api.isEmpty()) {
+ newApi.setStatus(RemoteApiStatus.NEW.toString());
+ newApi.setAddedVersion(apiSpec.getAppVersion());
+ newApi.setLatestVersion(apiSpec.getAppVersion());
+ remoteServiceRepo.save(newApi);
+ } else {
+ RemoteApi existApi = api.get();
+ BeanUtil.copyProperties(newApi, existApi, "id");
+ //TODO: 如何确认接口变更-暂时不确认
+ if (existApi.getBody().equalsIgnoreCase(newApi.getBody())) {
+ existApi.setStatus(RemoteApiStatus.IN_USE.toString());
+ existApi.setLatestVersion(apiSpec.getAppVersion());
+ } else {
+ existApi.setStatus(RemoteApiStatus.UPDATED.toString());
+ existApi.setLatestVersion(apiSpec.getAppVersion());
+ }
+ remoteServiceRepo.save(existApi);
+ }
+ }
+
+ public void updateStatusToEndOfLife(ApiSpecVersionModel apiSpec, PostmanItem postmanItem) {
+ Optional> apiListOptional = remoteServiceRepo.findRemoteApiByModuleNameAndServiceNameAndLatestVersionNot(
+ apiSpec.getName(),
+ postmanItem.getName(),
+ apiSpec.getAppVersion()
+ );
+ if (apiListOptional.isEmpty()) {
+ log.info("没有需要删除的数据");
+ } else {
+ List apiList = apiListOptional.get();
+ for (RemoteApi api : apiList) {
+ api.setStatus(RemoteApiStatus.END_OF_LIFE.toString());
+ remoteServiceRepo.save(api);
+ log.info("有需要删除的数据");
+ }
+
+ }
+ }
+
+
+}
+
+
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/package-info.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/package-info.java
new file mode 100644
index 0000000..b8c6392
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/package-info.java
@@ -0,0 +1 @@
+package io.fluent.qtm.pm;
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/FieldOption.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/FieldOption.java
new file mode 100644
index 0000000..d0727ce
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/FieldOption.java
@@ -0,0 +1,158 @@
+package io.fluent.qtm.pm.requirement;
+
+
+import io.fluent.base.model.ModelWithValidFlag;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.fun.ChoiceFetchHandler;
+import xyz.erupt.annotation.fun.VLModel;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.ChoiceType;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Erupt(name = "字段选项",
+ power = @Power(export = true, importable = true),
+ orderBy = "FieldOption.updateTime desc")
+@Table(name = "field_option")
+public class FieldOption extends ModelWithValidFlag implements ChoiceFetchHandler {
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",notNull = true
+ )
+ )
+ private String name;
+ @EruptField(
+ views = @View(
+ title = "字段code"
+ ),
+ edit = @Edit(
+ title = "字段code"
+ )
+ )
+ private String code;
+
+ @EruptField(
+ views = @View(title = "编辑类型"),
+ edit = @Edit(title = "编辑类型",
+ notNull = true, type = EditType.CHOICE,
+ choiceType = @ChoiceType(type = ChoiceType.Type.RADIO, fetchHandler = FieldOption.class))
+ )
+ private String type;
+
+ @EruptField(
+ views = @View(
+ title = "是否可以为空"
+ ),
+ edit = @Edit(
+ title = "是否可以为空",
+ type = EditType.BOOLEAN
+ )
+ )
+ private boolean notNull;
+ @EruptField(
+ views = @View(
+ title = "字段约束条件"
+ ),
+ edit = @Edit(
+ title = "字段约束条件",
+ type = EditType.CODE_EDITOR, notNull = true,
+ codeEditType = @CodeEditorType(language = "text"),
+ desc = "字段约束条件"
+ )
+ )
+ private String constrains;
+
+ @EruptField(
+ views = @View(
+ title = "和其他业务关系"
+ ),
+ edit = @Edit(
+ title = "和其他业务关系",
+ type = EditType.CODE_EDITOR,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String relatedTo;
+
+ @EruptField(
+ views = @View(title = "显示顺序", sortable = true),
+ edit = @Edit(title = "显示顺序", notNull = true)
+ )
+ private Integer sort;
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public boolean isNotNull() {
+ return notNull;
+ }
+
+ public void setNotNull(boolean notNull) {
+ this.notNull = notNull;
+ }
+
+ public String getConstrains() {
+ return constrains;
+ }
+
+ public void setConstrains(String constrains) {
+ this.constrains = constrains;
+ }
+
+ public String getRelatedTo() {
+ return relatedTo;
+ }
+
+ public void setRelatedTo(String relatedTo) {
+ this.relatedTo = relatedTo;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public void setSort(Integer sort) {
+ this.sort = sort;
+ }
+
+ @Override
+ public List fetch(String[] params) {
+ List list = new ArrayList<>();
+ for (FieldOptionType value : FieldOptionType.values()) {
+ list.add(new VLModel(value.name(), value.getDesc()));
+ }
+ return list;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/FieldOptionType.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/FieldOptionType.java
new file mode 100644
index 0000000..69b306b
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/FieldOptionType.java
@@ -0,0 +1,13 @@
+package io.fluent.qtm.pm.requirement;
+
+import lombok.Getter;
+
+@Getter
+public enum FieldOptionType {
+ NUMBER("数值"),STRING("字符串"),RELATION("关联"),DATE("日期"),ENUM("枚举"),BOOLEAN("布尔");
+
+ private String desc;
+ FieldOptionType(String desc) {
+ this.desc = desc;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/RequirementFeature.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/RequirementFeature.java
new file mode 100644
index 0000000..a91ffc6
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/RequirementFeature.java
@@ -0,0 +1,34 @@
+package io.fluent.qtm.pm.requirement;
+
+import io.fluent.base.model.ModelWithValidFlag;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Erupt(name = "需求功能点",
+ power = @Power(export = true, importable = true),
+ orderBy = "RequirementFeature.updateTime desc")
+@Table(name = "requirement_features")
+public class RequirementFeature extends ModelWithValidFlag {
+
+ @EruptField(
+ views = @View(
+ title = "业务功能相关说明"
+ ),
+ edit = @Edit(
+ title = "业务功能相关说明",
+ type = EditType.CODE_EDITOR, notNull = true,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String feature;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/RequirementType.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/RequirementType.java
new file mode 100644
index 0000000..23f7c44
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/RequirementType.java
@@ -0,0 +1,15 @@
+package io.fluent.qtm.pm.requirement;
+
+import lombok.Getter;
+
+@Getter
+public enum RequirementType {
+ CREATE("创建"),UPDATE("更新"),DELETE("删除/归档"),SEARCH("查询"), COMPLEX("复杂业务"),
+ WORKFLOW("工作流"),
+ REPORT("报表"),OTHER("其他");
+
+ private String desc;
+ RequirementType(String desc) {
+ this.desc = desc;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/TestRequirement.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/TestRequirement.java
new file mode 100644
index 0000000..31a5222
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/pm/requirement/TestRequirement.java
@@ -0,0 +1,192 @@
+package io.fluent.qtm.pm.requirement;
+
+
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlag;
+import io.fluent.base.product.model.ProductModuleModel;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.fun.ChoiceFetchHandler;
+import xyz.erupt.annotation.fun.VLModel;
+import xyz.erupt.annotation.sub_erupt.LinkTree;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.ChoiceType;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.annotation.sub_field.sub_edit.TagsType;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+
+@Entity
+@Erupt(name = "测试需求管理",
+ power = @Power(export = true, importable = true),
+ orderBy = "TestRequirement.updateTime desc",
+ linkTree = @LinkTree(field = "module"))
+@Table(name = "test_requirements")
+public class TestRequirement extends ModelWithValidFlag implements ChoiceFetchHandler {
+
+ @EruptField(
+ views = @View(title = "需求概述"),
+ edit = @Edit(title = "需求概述")
+ )
+ private String summary;
+
+ @EruptField(
+ views = @View(title = "需求类型"),
+ edit = @Edit(title = "需求类型",
+ notNull = true, type = EditType.CHOICE,
+ choiceType = @ChoiceType(type = ChoiceType.Type.RADIO,
+ fetchHandler = TestRequirement.class))
+ )
+ private String type;
+
+ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+ @JoinColumn(name = "test_req_id")
+ @EruptField(
+ edit = @Edit(title = "功能点", type = EditType.TAB_TABLE_ADD)
+ )
+ private Set features;
+
+
+ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+ @JoinColumn(name = "test_req_id")
+ @OrderBy("sort")
+ @EruptField(
+ edit = @Edit(title = "字段管理", type = EditType.TAB_TABLE_ADD)
+ )
+ private Set fieldOptions;
+
+ @ManyToOne
+ @JoinColumn(name = "product_id")
+ @EruptField(
+ views = @View(title = "所属模块", column = "details"),
+ edit = @Edit(
+ notNull = true,
+ search = @Search,
+ title = "产品模块选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ pid = "parent.id"))
+ )
+ private ProductModuleModel module;
+
+ @EruptField(
+ views = @View(
+ title = "提示词"
+ ),
+ edit = @Edit(
+ title = "提示词"
+ )
+ )
+ private String prompts;
+
+ @EruptField(
+ views = @View(
+ title = "优先级"
+ ),
+ edit = @Edit(
+ search = @Search,
+ title = "优先级",
+ type = EditType.TAGS,
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct key,detail from master_data where category_code = 'PRIORITY' order by 1 "
+ )
+ )
+ )
+ private String priority = "P2";
+
+ @EruptField(
+ views = @View(
+ title = "需求状态"
+ ),
+ edit = @Edit(
+ title = "需求状态"
+ )
+ )
+ private String status;
+
+ @Override
+ public List fetch(String[] params) {
+ List list = new ArrayList<>();
+ for (RequirementType value : RequirementType.values()) {
+ list.add(new VLModel(value.name(), value.getDesc()));
+ }
+ return list;
+ }
+
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+
+ public String getPrompts() {
+ return prompts;
+ }
+
+ public void setPrompts(String prompts) {
+ this.prompts = prompts;
+ }
+
+
+ public Set getFieldOptions() {
+ return fieldOptions;
+ }
+
+ public void setFieldOptions(Set fieldOptions) {
+ this.fieldOptions = fieldOptions;
+ }
+
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Set getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(Set features) {
+ this.features = features;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public ProductModuleModel getModule() {
+ return module;
+ }
+
+ public void setModule(ProductModuleModel module) {
+ this.module = module;
+ }
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/dto/TestCaseDTO.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/dto/TestCaseDTO.java
new file mode 100644
index 0000000..bc776ff
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/dto/TestCaseDTO.java
@@ -0,0 +1,28 @@
+package io.fluent.qtm.tc.dto;
+
+import com.github.crab2died.annotation.ExcelField;
+import lombok.Data;
+
+@Data
+public class TestCaseDTO {
+ @ExcelField(title = "产品名称")
+ private String productName;
+ @ExcelField(title = "模块名称")
+ private String moduleName;
+ @ExcelField(title = "功能点")
+ private String feature;
+ @ExcelField(title = "用例描述")
+ private String summary;
+ @ExcelField(title = "优先级")
+ private String priority = "P2"; //check it
+ @ExcelField(title = "用例前提条件")
+ private String precondition;
+ @ExcelField(title = "测试步骤")
+ private String steps;
+ @ExcelField(title = "期望结果")
+ private String expectedResult;
+
+ @ExcelField(title = "用例ID")
+ private String uuid;
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/handlers/GenerateTestRecordHandler.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/handlers/GenerateTestRecordHandler.java
new file mode 100644
index 0000000..cc87109
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/handlers/GenerateTestRecordHandler.java
@@ -0,0 +1,49 @@
+package io.fluent.qtm.tc.handlers;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import io.fluent.qtm.tc.model.TestCase;
+import io.fluent.qtm.tc.model.TestResult;
+import io.fluent.qtm.tc.model.TestRun;
+import io.fluent.qtm.tc.model.TestScenario;
+import io.fluent.qtm.tc.repo.TestResultRepo;
+
+import org.springframework.stereotype.Service;
+import xyz.erupt.annotation.fun.OperationHandler;
+
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Service
+public class GenerateTestRecordHandler implements OperationHandler {
+ @Resource
+ private TestResultRepo testResultRepo;
+
+ @Override
+ public String exec(List data, Void unused, String[] param) {
+ for (TestRun testRun : data) {
+ //get all test cases
+ for (TestCase testCase : testRun.getTestCases()) {
+ TestResult result = BeanUtil.copyProperties(testCase, TestResult.class);
+ result.setTestCaseUUID(testCase.getUuid());
+ result.setTestRun(testRun);
+ result.setQaOwner(testRun.getTestOwner());
+ testResultRepo.save(result);
+ }
+ for (TestScenario tc : testRun.getTestScenarios()) {
+ for (TestCase testCase : tc.getTestCases()) {
+ TestResult result = BeanUtil.copyProperties(testCase, TestResult.class);
+ result.setTestCaseUUID(testCase.getUuid());
+ result.setTestRun(testRun);
+ result.setQaOwner(testRun.getTestOwner());
+ result.setTestScenario(tc.getName());
+ testResultRepo.save(result);
+ }
+ }
+ }
+ return null;
+ }
+
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestCase.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestCase.java
new file mode 100644
index 0000000..2db1f68
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestCase.java
@@ -0,0 +1,238 @@
+package io.fluent.qtm.tc.model;
+
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlagVo;
+import io.fluent.base.product.model.ProductModuleModel;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.LinkTree;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.*;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+/**
+ *
+ */
+@Entity
+@Erupt(name = "测试用例",
+ power = @Power(export = true),
+ orderBy = "TestCase.updateTime desc",
+ linkTree = @LinkTree(field = "module"),layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30))
+@Table(name = "test_cases")
+public class TestCase extends ModelWithValidFlagVo {
+
+ @ManyToOne
+ @JoinColumn(name = "product_id")
+ @EruptField(
+ views = @View(title = "所属模块",column = "details"),
+ edit = @Edit(
+ notNull = true,
+ search = @Search,
+ title = "产品模块选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ pid = "parent.id"))
+ )
+ private ProductModuleModel module;
+
+ @ManyToOne
+ @JoinColumn(name = "parent_product_id")
+ @EruptField(
+ views = @View(title = "父模块",column = "details"),
+ edit = @Edit(
+ notNull = true,
+ search = @Search,
+ title = "产品模块选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ pid = "parent.id"))
+ )
+ private ProductModuleModel parent;
+
+ @ManyToOne
+ @JoinColumn(name = "root_product_id")
+ @EruptField(
+ views = @View(title = "所属产品",column = "details"),
+ edit = @Edit(
+ notNull = true,
+ search = @Search,
+ title = "产品模块选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(id = "id", label = "name",
+ pid = "parent.id"))
+ )
+ private ProductModuleModel product;
+
+ @EruptField(
+ views = @View(
+ title = "功能点"
+ ),
+ edit = @Edit(
+ title = "功能点",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String feature;
+ @EruptField(
+ views = @View(
+ title = "用例描述"
+ ),
+ edit = @Edit(
+ title = "用例描述",
+ type = EditType.INPUT, notNull = true
+ )
+ )
+ private String summary;
+
+ @EruptField(
+ views = @View(
+ title = "优先级"
+ ),
+ edit = @Edit(
+ title = "优先级",
+ type = EditType.TAGS,
+ search = @Search,
+ tagsType = @TagsType(
+ fetchHandler = SqlTagFetchHandler.class,
+ fetchHandlerParams = "select distinct key,detail from master_data where category_code = 'PRIORITY' order by 1 "
+ )
+ )
+ )
+ private String priority = "P2";
+
+
+ @EruptField(
+ views = @View(
+ title = "测试步骤"
+ ),
+ edit = @Edit(
+ title = "测试步骤",
+ type = EditType.CODE_EDITOR, notNull = true,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String steps;
+ @EruptField(
+ views = @View(
+ title = "期望结果"
+ ),
+ edit = @Edit(
+ title = "期望结果",
+ type = EditType.CODE_EDITOR,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String expectedResult;
+
+ @EruptField(
+ views = @View(
+ title = "用例ID"
+ )
+ )
+ private String uuid;
+ @EruptField(
+ views = @View(
+ title = "用例前提条件"
+ ),
+ edit = @Edit(
+ title = "用例前提条件",
+ type = EditType.CODE_EDITOR,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String precondition;
+
+ public String getFeature() {
+ return feature;
+ }
+
+ public void setFeature(String feature) {
+ this.feature = feature;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+ public String getSteps() {
+ return steps;
+ }
+
+ public void setSteps(String steps) {
+ this.steps = steps;
+ }
+
+ public String getExpectedResult() {
+ return expectedResult;
+ }
+
+ public void setExpectedResult(String expectedResult) {
+ this.expectedResult = expectedResult;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getPrecondition() {
+ return precondition;
+ }
+
+ public void setPrecondition(String precondition) {
+ this.precondition = precondition;
+ }
+
+
+ public ProductModuleModel getModule() {
+ return module;
+ }
+
+ public void setModule(ProductModuleModel module) {
+ this.module = module;
+ }
+
+ public ProductModuleModel getParent() {
+ return parent;
+ }
+
+ public void setParent(ProductModuleModel parent) {
+ this.parent = parent;
+ }
+
+ public ProductModuleModel getProduct() {
+ return product;
+ }
+
+ public void setProduct(ProductModuleModel product) {
+ this.product = product;
+ }
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestResult.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestResult.java
new file mode 100644
index 0000000..63039fb
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestResult.java
@@ -0,0 +1,206 @@
+package io.fluent.qtm.tc.model;
+
+
+import io.fluent.base.model.ModelWithValidFlagVo;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.LinkTree;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.CodeEditorType;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+
+@Table(name = "test_results")
+@Entity
+@Erupt(name = "测试执行结果",
+ power = @Power(importable = true, export = true)
+ , linkTree = @LinkTree(field = "testRun")
+)
+public class TestResult extends ModelWithValidFlagVo {
+ @ManyToOne
+ @EruptField(
+ views = @View(title = "所属测试安排", column = "name"),
+ edit = @Edit(title = "所属测试安排", type = EditType.REFERENCE_TREE,
+ referenceTreeType = @ReferenceTreeType(pid = "parent.id", expandLevel = 2))
+ )
+ private TestRun testRun;
+
+ @EruptField(
+ views = @View(
+ title = "测试场景"
+ ),
+ edit = @Edit(
+ title = "测试场景",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String testScenario;
+ @EruptField(
+ views = @View(
+ title = "功能点"
+ ),
+ edit = @Edit(
+ title = "功能点",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String feature;
+ @EruptField(
+ views = @View(
+ title = "用例描述"
+ ),
+ edit = @Edit(
+ title = "用例描述",
+ type = EditType.INPUT, notNull = true
+ )
+ )
+ private String summary;
+ @EruptField(
+ views = @View(
+ title = "用例优先级"
+ ),
+ edit = @Edit(
+ title = "用例优先级",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String priority = "P2"; //check it
+ @EruptField(
+ views = @View(
+ title = "测试步骤"
+ ),
+ edit = @Edit(
+ title = "测试步骤",
+ type = EditType.CODE_EDITOR, notNull = true,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String steps;
+ @EruptField(
+ views = @View(
+ title = "用例期望结果"
+ ),
+ edit = @Edit(
+ title = "用例期望结果",
+ type = EditType.CODE_EDITOR, notNull = true,
+ codeEditType = @CodeEditorType(language = "text")
+ )
+ )
+ private String expectedResult;
+
+
+ @EruptField(
+ views = @View(
+ title = "测试测试结果"
+ ),
+ edit = @Edit(
+ title = "测试测试结果",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String qaTestResult;
+
+
+ @EruptField(
+ views = @View(
+ title = "测试负责人"
+ ),
+ edit = @Edit(
+ title = "测试负责人",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String qaOwner;
+
+ private String testCaseUUID;
+
+
+ public String getTestCaseUUID() {
+ return testCaseUUID;
+ }
+
+ public void setTestCaseUUID(String testCaseUUID) {
+ this.testCaseUUID = testCaseUUID;
+ }
+
+ public String getFeature() {
+ return feature;
+ }
+
+ public void setFeature(String feature) {
+ this.feature = feature;
+ }
+
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+ public String getSteps() {
+ return steps;
+ }
+
+ public void setSteps(String steps) {
+ this.steps = steps;
+ }
+
+ public String getExpectedResult() {
+ return expectedResult;
+ }
+
+ public void setExpectedResult(String expectedResult) {
+ this.expectedResult = expectedResult;
+ }
+
+
+ public String getQaTestResult() {
+ return qaTestResult;
+ }
+
+ public void setQaTestResult(String qaTestResult) {
+ this.qaTestResult = qaTestResult;
+ }
+
+ public String getQaOwner() {
+ return qaOwner;
+ }
+
+ public void setQaOwner(String qaOwner) {
+ this.qaOwner = qaOwner;
+ }
+
+ public TestRun getTestRun() {
+ return testRun;
+ }
+
+ public void setTestRun(TestRun testRun) {
+ this.testRun = testRun;
+ }
+
+ public String getTestScenario() {
+ return testScenario;
+ }
+
+ public void setTestScenario(String testScenario) {
+ this.testScenario = testScenario;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestRun.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestRun.java
new file mode 100644
index 0000000..47c9af6
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestRun.java
@@ -0,0 +1,251 @@
+package io.fluent.qtm.tc.model;
+
+
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.qtm.tc.handlers.GenerateTestRecordHandler;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_erupt.RowOperation;
+import xyz.erupt.annotation.sub_erupt.Tree;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.BoolType;
+import xyz.erupt.annotation.sub_field.sub_edit.ReferenceTreeType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.persistence.*;
+import java.time.LocalDate;
+import java.util.Set;
+
+//TODO: Filter By Status
+//TODO: input by Uploaded File or File Sync
+@Entity
+@Table(name = "test_runs")
+@Erupt(name = "测试执行计划",
+ power = @Power(importable = true, export = true),
+ tree = @Tree(id = "id", label = "name", pid = "parent.id")
+ ,rowOperation = {@RowOperation(
+ title = "生成执行测试用例",
+ operationHandler = GenerateTestRecordHandler.class)}
+)
+
+public class TestRun extends MetaModel {
+
+ @ManyToOne
+ @JoinColumn(name = "product_id")
+ @EruptField(
+ views = @View(title = "产品名称", column = "name"),
+ edit = @Edit(
+ search = @Search,
+ title = "产品选择",
+ type = EditType.REFERENCE_TREE,
+ desc = "动态获取产品",
+ referenceTreeType = @ReferenceTreeType(
+ pid = "parent.id"))
+ )
+ private ProductModuleModel product;
+
+ @ManyToOne
+ @EruptField(
+ edit = @Edit(
+ title = "父级测试安排",
+ type = EditType.REFERENCE_TREE,
+ referenceTreeType = @ReferenceTreeType(pid = "parent.id")
+ )
+ )
+ private TestRun parent;
+
+
+ @EruptField(
+ views = @View(
+ title = "测试负责人"
+ ),
+ edit = @Edit(
+ title = "测试负责人",
+ type = EditType.INPUT, search = @Search
+ )
+ )
+ private String testOwner;
+
+ @JoinTable(name = "test_run_cases",
+ joinColumns = @JoinColumn(name = "test_run_id", referencedColumnName = "id"),
+ inverseJoinColumns = @JoinColumn(name = "test_case_id", referencedColumnName = "id"))
+ @ManyToMany(fetch = FetchType.EAGER)
+ @EruptField(
+ views = @View(title = "包含用例"),
+ edit = @Edit(
+ title = "包含用例",
+ type = EditType.TAB_TABLE_REFER
+ )
+ )
+ private Set testCases;
+
+ @JoinTable(name = "test_run_scenario",
+ joinColumns = @JoinColumn(name = "test_run_id", referencedColumnName = "id"),
+ inverseJoinColumns = @JoinColumn(name = "test_scenario_id", referencedColumnName = "id"))
+ @ManyToMany(fetch = FetchType.EAGER)
+ @EruptField(
+ views = @View(title = "包含测试场景"),
+ edit = @Edit(
+ title = "包含测试场景",
+ type = EditType.TAB_TABLE_REFER
+ )
+ )
+ private Set testScenarios;
+
+ public ProductModuleModel getProduct() {
+ return product;
+ }
+
+ public void setProduct(ProductModuleModel product) {
+ this.product = product;
+ }
+
+ public String getTestOwner() {
+ return testOwner;
+ }
+
+ public void setTestOwner(String testOwner) {
+ this.testOwner = testOwner;
+ }
+
+ public Set getTestCases() {
+ return testCases;
+ }
+
+ public void setTestCases(Set testCases) {
+ this.testCases = testCases;
+ }
+
+ public Set getTestScenarios() {
+ return testScenarios;
+ }
+
+ public void setTestScenarios(Set testScenarios) {
+ this.testScenarios = testScenarios;
+ }
+
+ public TestRun getParent() {
+ return parent;
+ }
+
+ public void setParent(TestRun parent) {
+ this.parent = parent;
+ }
+
+ @EruptField(
+ views = @View(
+ title = "名称"
+ ),
+ edit = @Edit(
+ title = "名称",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String name;
+ @EruptField(
+ views = @View(
+ title = "详细"
+ ),
+ edit = @Edit(
+ title = "详细",
+ type = EditType.INPUT, search = @Search, notNull = true
+ )
+ )
+ private String detail;
+ @EruptField(
+ views = @View(
+ title = "开始时间"
+ ),
+ edit = @Edit(
+ title = "开始时间",
+ type = EditType.DATE, search = @Search,
+ boolType = @BoolType
+ )
+ )
+ private LocalDate startDate;
+ @EruptField(
+ views = @View(
+ title = "预计完成时间"
+ ),
+ edit = @Edit(
+ title = "预计完成时间",
+ type = EditType.DATE, search = @Search,
+ boolType = @BoolType
+ )
+ )
+ private LocalDate estimatedCompletedDate;
+ @EruptField(
+ views = @View(
+ title = "完成时间"
+ ),
+ edit = @Edit(
+ title = "完成时间",
+ type = EditType.DATE, search = @Search,
+ boolType = @BoolType
+ )
+ )
+ private LocalDate completedDate;
+ @EruptField(
+ views = @View(
+ title = "当前状态"
+ ),
+ edit = @Edit(
+ title = "当前状态",
+ type = EditType.INPUT, search = @Search, notNull = true,
+ boolType = @BoolType
+ )
+ )
+ private String status;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDetail() {
+ return detail;
+ }
+
+ public void setDetail(String detail) {
+ this.detail = detail;
+ }
+
+ public LocalDate getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(LocalDate startDate) {
+ this.startDate = startDate;
+ }
+
+ public LocalDate getEstimatedCompletedDate() {
+ return estimatedCompletedDate;
+ }
+
+ public void setEstimatedCompletedDate(LocalDate estimatedCompletedDate) {
+ this.estimatedCompletedDate = estimatedCompletedDate;
+ }
+
+ public LocalDate getCompletedDate() {
+ return completedDate;
+ }
+
+ public void setCompletedDate(LocalDate completedDate) {
+ this.completedDate = completedDate;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestScenario.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestScenario.java
new file mode 100644
index 0000000..58478ab
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/model/TestScenario.java
@@ -0,0 +1,43 @@
+package io.fluent.qtm.tc.model;
+
+import io.fluent.base.model.NamedModelVO;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+
+import javax.persistence.*;
+import java.util.Set;
+
+@Entity
+@Table(name = "test_scenarios")
+@Erupt(name = "测试场景管理",
+ power = @Power(importable = true, export = true)
+)
+//@PreDataProxy(value= TestScenarioCaseProxy.class)
+
+public class TestScenario extends NamedModelVO {
+
+ @JoinTable(name = "test_scenario_cases",
+ joinColumns = @JoinColumn(name = "test_scenario_id", referencedColumnName = "id"),
+ inverseJoinColumns = @JoinColumn(name = "test_case_id", referencedColumnName = "id"))
+ @ManyToMany(fetch = FetchType.EAGER)
+ @EruptField(
+ views = @View(title = "包含用例"),
+ edit = @Edit(
+ title = "包含用例",
+ type = EditType.TAB_TABLE_REFER
+ )
+ )
+ private Set testCases;
+
+ public Set getTestCases() {
+ return testCases;
+ }
+
+ public void setTestCases(Set testCases) {
+ this.testCases = testCases;
+ }
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/package-info.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/package-info.java
new file mode 100644
index 0000000..0f28f0f
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/package-info.java
@@ -0,0 +1 @@
+package io.fluent.qtm.tc;
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestCaseRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestCaseRepo.java
new file mode 100644
index 0000000..354138a
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestCaseRepo.java
@@ -0,0 +1,15 @@
+package io.fluent.qtm.tc.repo;
+
+import io.fluent.qtm.tc.model.TestCase;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface TestCaseRepo extends JpaRepository {
+ public TestCase findByUuid(String uuid);
+
+
+// @Query(nativeQuery = true,value = "delete from test_cases where test_plan=:testPlan")
+// @Modifying
+// public void deleteByTestPlan(@Param("testPlan") String testPlan);
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestResultRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestResultRepo.java
new file mode 100644
index 0000000..570f55a
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestResultRepo.java
@@ -0,0 +1,11 @@
+package io.fluent.qtm.tc.repo;
+
+
+import io.fluent.qtm.tc.model.TestResult;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository(value = "testResultRepo")
+public interface TestResultRepo extends JpaRepository {
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestRunRepo.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestRunRepo.java
new file mode 100644
index 0000000..f84b76c
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/repo/TestRunRepo.java
@@ -0,0 +1,11 @@
+package io.fluent.qtm.tc.repo;
+
+
+import io.fluent.qtm.tc.model.TestRun;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface TestRunRepo extends JpaRepository {
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/TestCaseService.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/TestCaseService.java
new file mode 100644
index 0000000..d4cda3f
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/TestCaseService.java
@@ -0,0 +1,14 @@
+package io.fluent.qtm.tc.service;
+
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.qtm.tc.dto.TestCaseDTO;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public interface TestCaseService {
+
+ public void saveTestCases(List cases,
+ ProductModuleModel product, ProductModuleModel module,String updater);
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/impl/MindMappingService.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/impl/MindMappingService.java
new file mode 100644
index 0000000..28dad0b
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/impl/MindMappingService.java
@@ -0,0 +1,41 @@
+package io.fluent.qtm.tc.service.impl;
+
+
+
+import cn.hutool.core.bean.BeanUtil;
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.qtm.tc.dto.TestCaseDTO;
+import io.fluent.qtm.tc.service.TestCaseService;
+import io.fluent.mindmap.api.MindMapAccessor;
+import org.springframework.stereotype.Service;
+import xyz.erupt.jpa.model.MetaModel;
+
+import javax.annotation.Resource;
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * 1.Import MindMapping file to test case database
+ * 2.export selected test cases as mindmapping file
+ */
+//TODO: convert to same TestCase Converter
+@Service("mindMappingService")
+public class MindMappingService {
+
+ @Resource
+ private TestCaseService testCaseService;
+
+ public List toTestCaseModel(String xmlFilePath) {
+ MindMapAccessor accessor = new MindMapAccessor();
+ return accessor.readMindMapToBean(xmlFilePath, TestCaseDTO.class);
+ }
+
+ @Transactional
+ public void saveTestCases(String xmlFilePath, MetaModel model) {
+ List testCaseModels = toTestCaseModel(xmlFilePath);
+ ProductModuleModel product = BeanUtil.getProperty(model, "product");
+ ProductModuleModel module = BeanUtil.getProperty(model, "module");
+ testCaseService.saveTestCases(testCaseModels,product,module,model.getUpdateBy());
+ }
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/impl/TestCaseServiceImpl.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/impl/TestCaseServiceImpl.java
new file mode 100644
index 0000000..7fdb66d
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/tc/service/impl/TestCaseServiceImpl.java
@@ -0,0 +1,94 @@
+package io.fluent.qtm.tc.service.impl;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.UUID;
+import cn.hutool.core.util.StrUtil;
+import io.fluent.base.proxies.AuditDataEnhancerProxy;
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.base.product.service.ProductModuleService;
+import io.fluent.qtm.tc.dto.TestCaseDTO;
+import io.fluent.qtm.tc.model.TestCase;
+import io.fluent.qtm.tc.repo.TestCaseRepo;
+import io.fluent.qtm.tc.service.TestCaseService;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.transaction.Transactional;
+import java.util.List;
+
+@Service
+public class TestCaseServiceImpl implements TestCaseService {
+ @Resource
+ private TestCaseRepo testCaseRepo;
+ @Resource
+ private ProductModuleService productMetaService;
+
+ @Resource
+ private AuditDataEnhancerProxy dataEnhancerProxy;
+ @Override
+ @Transactional
+ @Async
+ /**
+ * notice:parent Product can't be created,parent product must be configured
+ * 1. 如果UUID没有或者找不到,则新增测试用例
+ * 2. 新增测试用例中,
+ */
+ public void saveTestCases(List cases,
+ ProductModuleModel parentProduct,
+ ProductModuleModel module,String updater) {
+ for (TestCaseDTO aCase : cases) {
+ TestCase tcEntity = createOrUseExistingTestCase(aCase);
+ ProductModuleModel rootProduct = getRootProductMeta(aCase);
+ ProductModuleModel parentModule = productMetaService.createModuleIfNotExist(rootProduct.getId(),
+ aCase.getModuleName(),updater);
+ ProductModuleModel subModule = whichSubModule(parentModule, aCase,updater);
+ tcEntity.setModule(subModule);
+ tcEntity.setProduct(rootProduct);
+ tcEntity.setParent(parentModule);
+ if (StrUtil.isBlankIfStr(aCase.getPriority())) {
+ tcEntity.setPriority("P2");
+ }
+ tcEntity.setSteps(StrUtil.join(":\n", aCase.getFeature(),
+ aCase.getSummary(), aCase.getSteps()));
+
+ testCaseRepo.save(tcEntity);
+ }
+ }
+
+ private TestCase createOrUseExistingTestCase(TestCaseDTO aCase) {
+ TestCase tcEntity;
+ if (StrUtil.isBlank(aCase.getUuid())) {
+ tcEntity = BeanUtil.copyProperties(aCase, TestCase.class);
+ tcEntity.setUuid(UUID.fastUUID().toString(true));
+
+ } else {
+ tcEntity = testCaseRepo.findByUuid(aCase.getUuid());
+ if (tcEntity == null) {
+ tcEntity = BeanUtil.copyProperties(aCase, TestCase.class); //生成新的的UUID
+ } else {
+ BeanUtil.copyProperties(aCase, tcEntity, "id"); //更新数据库数据
+ }
+ }
+ return tcEntity;
+ }
+
+
+ private ProductModuleModel getRootProductMeta(TestCaseDTO aCase) {
+ ProductModuleModel rootProductMeta = productMetaService.findByName(aCase.getProductName());
+ if (rootProductMeta == null) {
+ throw new RuntimeException("找不到产品");
+ }
+ return rootProductMeta;
+ }
+
+
+ private ProductModuleModel whichSubModule(ProductModuleModel parentProduct, TestCaseDTO aCase,String updater) {
+ if (parentProduct.getName().equalsIgnoreCase(aCase.getModuleName())) return parentProduct;
+ return productMetaService.createModuleIfNotExist(parentProduct.getId(), aCase.getModuleName(),updater);
+
+ }
+
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/model/UploadFileModel.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/model/UploadFileModel.java
new file mode 100644
index 0000000..bf185b0
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/model/UploadFileModel.java
@@ -0,0 +1,62 @@
+package io.fluent.qtm.upload.model;
+
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.qtm.upload.proxy.UploadFileDataProxy;
+import lombok.Data;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.PreDataProxy;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.AttachmentType;
+import xyz.erupt.annotation.sub_field.sub_edit.ChoiceType;
+import xyz.erupt.annotation.sub_field.sub_edit.InputType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.toolkit.handler.SqlChoiceFetchHandler;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Erupt(name = "测试相关文件上传同步", orderBy = "UploadFileModel.createTime desc")
+@Table(name = "uploaded_files")
+@Entity
+@Data
+@PreDataProxy(value = UploadFileDataProxy.class)
+public class UploadFileModel extends ProductModuleModel {
+
+ @EruptField(
+ views = @View(title = "用途"),
+ edit = @Edit(
+ search = @Search,
+ title = "获取可选类型",
+ type = EditType.CHOICE,
+ desc = "动态获取可选类型",
+ notNull = true,
+ choiceType = @ChoiceType(
+ fetchHandler = SqlChoiceFetchHandler.class,
+ fetchHandlerParams = "select distinct code,name from master_data where category='UPLOAD_FILE_USAGE' and valid=true"
+ ))
+ )
+ private String usage;
+
+
+ @EruptField(
+ views = @View(title = "文件上传"),
+ edit = @Edit(title = "文件上传", type = EditType.ATTACHMENT,
+ attachmentType = @AttachmentType(size = 100000))
+ )
+ private String attachment;
+
+ @EruptField(
+ views = @View(
+ title = "用途描述"
+ ),
+ edit = @Edit(
+ title = "用途描述",
+ type = EditType.TEXTAREA, notNull = true,
+ inputType = @InputType
+ )
+ )
+ private String comments;
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/package-info.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/package-info.java
new file mode 100644
index 0000000..3a084f9
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/package-info.java
@@ -0,0 +1 @@
+package io.fluent.qtm.upload;
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/proxy/UploadFileDataProxy.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/proxy/UploadFileDataProxy.java
new file mode 100644
index 0000000..193c7ca
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/proxy/UploadFileDataProxy.java
@@ -0,0 +1,64 @@
+package io.fluent.qtm.upload.proxy;
+
+
+
+import cn.hutool.core.bean.BeanUtil;
+import io.fluent.excel.ExcelReadWriter;
+import io.fluent.base.product.model.ProductModuleModel;
+import io.fluent.qtm.tc.dto.TestCaseDTO;
+import io.fluent.qtm.tc.service.TestCaseService;
+import io.fluent.qtm.tc.service.impl.MindMappingService;
+import lombok.extern.slf4j.Slf4j;
+import xyz.erupt.core.prop.EruptProp;
+import xyz.erupt.core.util.EruptSpringUtil;
+import xyz.erupt.jpa.model.MetaDataProxy;
+import xyz.erupt.jpa.model.MetaModel;
+
+import java.util.List;
+
+@Slf4j
+public class UploadFileDataProxy extends MetaDataProxy {
+ private final MindMappingService mindMappingService;
+ private final TestCaseService testCaseService;
+ private final EruptProp eruptProp;
+ private final ExcelReadWriter excelReadWriter;
+
+ public UploadFileDataProxy() {
+ mindMappingService = EruptSpringUtil.getBean(MindMappingService.class);
+ testCaseService = EruptSpringUtil.getBean(TestCaseService.class);
+ eruptProp = EruptSpringUtil.getBean(EruptProp.class);
+ excelReadWriter = new ExcelReadWriter();
+ }
+
+ @Override
+ public void beforeAdd(MetaModel metaModel) {
+ //before add, add some check here
+ super.beforeAdd(metaModel);
+ }
+
+ @Override
+ public void afterAdd(MetaModel metaModel) {
+ //after add, then doing business process
+ log.info("start handler uploaded file");
+ String filePath = getUploaderFilePath(metaModel);
+ String uploadType = BeanUtil.getProperty(metaModel, "usage");
+
+ if(UploadFileTypeEnum.parseType(uploadType).equals(UploadFileTypeEnum.EXCEL_TC)){
+ ProductModuleModel product = BeanUtil.getProperty(metaModel, "product");
+ ProductModuleModel module = BeanUtil.getProperty(metaModel, "module");
+ testCaseService.saveTestCases(getExcelTestCases(filePath),product,module,metaModel.getUpdateBy());
+ }
+ if(UploadFileTypeEnum.parseType(uploadType).equals(UploadFileTypeEnum.FREEMIND)){
+ mindMappingService.saveTestCases(filePath,metaModel);
+ }
+ }
+
+ private List getExcelTestCases(String filePath){
+ return excelReadWriter.readExcel(filePath, TestCaseDTO.class);
+ }
+
+ private String getUploaderFilePath(MetaModel metaModel) {
+ return eruptProp.getUploadPath() + BeanUtil.getProperty(metaModel, "attachment");
+ }
+
+}
diff --git a/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/proxy/UploadFileTypeEnum.java b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/proxy/UploadFileTypeEnum.java
new file mode 100644
index 0000000..7854549
--- /dev/null
+++ b/fluent-apps/workspace/src/main/java/io/fluent/qtm/upload/proxy/UploadFileTypeEnum.java
@@ -0,0 +1,14 @@
+package io.fluent.qtm.upload.proxy;
+
+public enum UploadFileTypeEnum {
+ EXCEL_TC,FREEMIND,PM,MINDMAP;
+
+ public static UploadFileTypeEnum parseType(String uploadFileType) {
+ for (UploadFileTypeEnum uploadFileTypeEnum : UploadFileTypeEnum.values()) {
+ if (uploadFileTypeEnum.name().equals(uploadFileType)) {
+ return uploadFileTypeEnum;
+ }
+ }
+ throw new RuntimeException("UploadFileTypeEnum is not found for " + uploadFileType);
+ }
+}
diff --git a/fluent-apps/feeds/src/main/resources/application-dev.yaml b/fluent-apps/workspace/src/main/resources/application-dev.yaml
similarity index 71%
rename from fluent-apps/feeds/src/main/resources/application-dev.yaml
rename to fluent-apps/workspace/src/main/resources/application-dev.yaml
index 17106a1..97197cc 100644
--- a/fluent-apps/feeds/src/main/resources/application-dev.yaml
+++ b/fluent-apps/workspace/src/main/resources/application-dev.yaml
@@ -21,9 +21,20 @@ erupt:
# 是否记录操作日志,默认true,该功能开启后可在【系统管理 → 操作日志】中查看操作日志
security.recordOperateLog: false
+#spring:
+# datasource:
+# url: jdbc:postgresql://db.supabase.orb.local:5432/postgres?currentSchema=workspace
+# username: postgres
+# password: postgres
+# jpa:
+# show-sql: true
+# generate-ddl: true
+# database-platform: org.hibernate.dialect.PostgreSQLDialect
+# database: postgresql
+
spring:
datasource:
- url: jdbc:postgresql://db.supabase.orb.local:5432/feeds
+ url: jdbc:postgresql://db.supabase.orb.local:5432/workspace
username: postgres
password: postgres
jpa:
@@ -31,7 +42,6 @@ spring:
generate-ddl: true
database-platform: org.hibernate.dialect.PostgreSQLDialect
database: postgresql
-
# mail:
# username: xxxx@qq.com
# password: xxxxxxx
@@ -62,8 +72,7 @@ knife4j:
enable: true
openapi:
title: QA Workspace API
- description: "`QA Workspace API
- # workspace"
+ description: "`QA Workspace API workspace"
email: fluentqa@163.com
concat: fluent-qa
# url: https://docs.xiaominfo.com
@@ -88,12 +97,32 @@ server:
includeStacktrace: ALWAYS
includeMessage: ALWAYS
port: 9090
+
+# Enhanced logging configuration
logging:
level:
- root: DEBUG
- org.hibernate: DEBUG
+ root: INFO
+ io.fluentqa: DEBUG
+ org.hibernate: INFO
io.fluent: DEBUG
xyz.erupt: DEBUG
+ org.springframework: DEBUG
+ org.springframework.boot: DEBUG
+ org.springframework.boot.autoconfigure: DEBUG
+ org.springframework.context: DEBUG
+ org.springframework.beans: DEBUG
+ org.springframework.jdbc: DEBUG
+ org.springframework.orm: DEBUG
+ org.hibernate.SQL: DEBUG
+ org.hibernate.type.descriptor.sql: TRACE
+ pattern:
+ console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+ file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
+ file:
+ name: ../temp/qam-application.log
+
+# Enable Spring Boot debug mode
+debug: true
magic-api:
web: /fluentapi/v1
diff --git a/fluent-apps/feeds/src/main/resources/application.yaml b/fluent-apps/workspace/src/main/resources/application.yaml
similarity index 100%
rename from fluent-apps/feeds/src/main/resources/application.yaml
rename to fluent-apps/workspace/src/main/resources/application.yaml
diff --git a/fluent-apps/workspace/src/main/resources/public/app.css b/fluent-apps/workspace/src/main/resources/public/app.css
new file mode 100644
index 0000000..44c63ae
--- /dev/null
+++ b/fluent-apps/workspace/src/main/resources/public/app.css
@@ -0,0 +1,24 @@
+layout-header {
+ background: #3f51b5 !important;
+}
+
+/* 例:修改登录页样式 */
+layout-passport > .container {
+ background-position: center !important;
+ background-repeat: repeat !important;
+ background-size: cover !important;
+ background-color: #fff !important;
+ background-image: url(https://www.erupt.xyz/demo/login-bg.svg) !important;
+}
+
+layout-passport .title {
+ font-family: Courier New, Menlo, Monaco, Consolas, monospace !important;
+}
+
+layout-passport form {
+ padding: 26px !important;
+ margin: 8px !important;
+ background: rgba(255, 255, 255, 0.9);
+ border-radius: 3px;
+ box-shadow: 1px 1px 10px rgba(190, 184, 184, 0.3);
+}
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/resources/public/app.js b/fluent-apps/workspace/src/main/resources/public/app.js
new file mode 100644
index 0000000..c4435ce
--- /dev/null
+++ b/fluent-apps/workspace/src/main/resources/public/app.js
@@ -0,0 +1,71 @@
+window.eruptSiteConfig = {
+ //erupt接口地址,在前后端分离时指定
+ domain: "",
+ //附件地址,一般情况下不需要指定,如果自定义对象存储空间,则需在此指定附件资源访问地址
+ fileDomain: "",
+ //标题
+ title: "QA Workspace",
+ //描述
+ desc: "QA Base",
+ //是否展示版权信息
+ copyright: true,
+ //高德地图 api key,使用地图组件须指定此属性,amapKey获取地址:https://lbs.amap.com (服务平台为:Web端(JS API))
+ amapKey: "xxxx",
+ //高德地图 SecurityJsCode
+ amapSecurityJsCode: "xxxxx",
+ //logo路径
+ logoPath: "erupt.svg",
+ //logo文字
+ logoText: "erupt",
+ //注册页地址(仅是一个链接,需要自定义实际样式)
+ registerPage: "",
+ //自定义导航栏按钮,配置后将会出现在页面右上角
+ r_tools: [{
+ text: "自定义功能按钮",
+ icon: "fa-eercast",
+ mobileHidden: true,
+ click: function (event) {
+ alert("Function button");
+ }
+ }],
+ // //登录成功事件
+ // login: function(user){
+ //
+ // },
+ // //注销事件
+ // logout: function(user){
+ //
+ // }
+};
+
+// //路由回调函数
+// window.eruptRouterEvent = {
+// //key表示要监听的路由切换地址,为url hash地址最后一段
+// //例如:http://www.erupt.xyz:9999/#/build/table/demo中demo为回调key
+// demo: {
+// //路由载入事件
+// load: function (e) {
+//
+// },
+// //路由退出事件
+// unload: function (e) {
+//
+// }
+// },
+// //$ 为全路径通配符,在任何路由切换时都会执行load与unload事件
+// $: {
+// load: function (e) {
+//
+// },
+// unload: function (e) {
+// }
+// }
+// };
+//
+// //erupt生命周期函数
+// window.eruptEvent = {
+// //页面加载完成后回调
+// startup: function () {
+//
+// }
+// }
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/resources/public/home.html b/fluent-apps/workspace/src/main/resources/public/home.html
new file mode 100644
index 0000000..35600cf
--- /dev/null
+++ b/fluent-apps/workspace/src/main/resources/public/home.html
@@ -0,0 +1,12 @@
+
+
+
+ home
+
+
+
+
+
+测试管理工具箱
+
+
\ No newline at end of file
diff --git a/fluent-apps/workspace/src/main/resources/tpl/operation.tpl b/fluent-apps/workspace/src/main/resources/tpl/operation.tpl
new file mode 100644
index 0000000..d77f7e5
--- /dev/null
+++ b/fluent-apps/workspace/src/main/resources/tpl/operation.tpl
@@ -0,0 +1,17 @@
+
+
+
+ <#list rows as row>
+
+ ${row.id}
+ ${row.choice!''}
+ ${row.code!''}
+
+ #list>
+
+
\ No newline at end of file
diff --git a/fluent-erupts/fleunt-github/pom.xml b/fluent-erupts/fleunt-github/pom.xml
index 40ea14e..2474f80 100644
--- a/fluent-erupts/fleunt-github/pom.xml
+++ b/fluent-erupts/fleunt-github/pom.xml
@@ -45,7 +45,7 @@
io.fluent
fluent-git
1.0-SNAPSHOT
- compile
+
\ No newline at end of file
diff --git a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/FluentGithubModule.java b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/FluentGithubModule.java
index 4ac5ad3..1535f73 100644
--- a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/FluentGithubModule.java
+++ b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/FluentGithubModule.java
@@ -2,6 +2,7 @@
import io.fluent.github.model.AwesomeResource;
import io.fluent.github.model.GithubStarredRepo;
+import io.fluent.github.model.GithubTrendingRepo;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
@@ -51,6 +52,12 @@ public List initMenus() {
awesomeModule.setName("awesomes");
awesomeModule.setCode("$awesomes");
menus.add(awesomeModule);
+
+ MetaMenu trendingReposModule = MetaMenu.createEruptClassMenu(GithubTrendingRepo.class, menus.get(0), 2, MenuTypeEnum.TABLE);
+ trendingReposModule.setIcon("fa fa-star");
+ trendingReposModule.setName("github trending");
+ trendingReposModule.setCode("$github-trending");
+ menus.add(trendingReposModule);
return menus;
}
diff --git a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/jobs/GithubStarredCollectorJob.java b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/jobs/GithubStarredCollectorJob.java
index dad8c8a..ecc6137 100644
--- a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/jobs/GithubStarredCollectorJob.java
+++ b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/jobs/GithubStarredCollectorJob.java
@@ -5,6 +5,7 @@
import io.fluent.github.service.GithubService;
import io.fluent.github.jobs.github.GithubJobFetchParameters;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import xyz.erupt.core.annotation.EruptHandlerNaming;
import xyz.erupt.job.handler.EruptJobHandler;
@@ -32,11 +33,15 @@ public String exec(String code, String param) {
}else {
parameters = JSONUtil.toBean(param, GithubJobFetchParameters.class);
}
+ saveGithubRepos(parameters);
+ return "success";
+ }
+
+ private void saveGithubRepos(GithubJobFetchParameters parameters) {
List userNames=StringUtils.split(parameters.getUserNames(),",");
for (String userName : userNames) {
- githubService.saveUserStarredRepo(userName,parameters.getFromPage());
+ githubService.saveUserStarredRepo(userName, parameters.getFromPage());
}
- return "success";
}
diff --git a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubStarredRepo.java b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubStarredRepo.java
index 38cff49..596f044 100644
--- a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubStarredRepo.java
+++ b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubStarredRepo.java
@@ -23,8 +23,11 @@
public class GithubStarredRepo extends MetaModelVo {
@EruptField(views = @View(title = "名称"), edit = @Edit(title = "名称", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
private String name;
+ @EruptField(views = @View(title = "htmlUrl"), edit = @Edit(title = "htmlUrl", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String htmlUrl;
@EruptField(views = @View(title = "URL"), edit = @Edit(title = "URL", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
private String url;
+
@EruptField(views = @View(title = "全名"), edit = @Edit(title = "全名", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
private String fullName;
diff --git a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubTrendingRepo.java b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubTrendingRepo.java
new file mode 100644
index 0000000..81bd4b0
--- /dev/null
+++ b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/model/GithubTrendingRepo.java
@@ -0,0 +1,53 @@
+package io.fluent.github.model;
+
+import lombok.Data;
+import xyz.erupt.annotation.Erupt;
+import xyz.erupt.annotation.EruptField;
+import xyz.erupt.annotation.sub_erupt.Layout;
+import xyz.erupt.annotation.sub_erupt.Power;
+import xyz.erupt.annotation.sub_field.Edit;
+import xyz.erupt.annotation.sub_field.EditType;
+import xyz.erupt.annotation.sub_field.View;
+import xyz.erupt.annotation.sub_field.sub_edit.InputType;
+import xyz.erupt.annotation.sub_field.sub_edit.Search;
+import xyz.erupt.jpa.model.MetaModelVo;
+
+import javax.persistence.Entity;
+import java.util.Date;
+
+@Data
+@Entity
+@Erupt(name = "Github Trending Repos",
+ power = @Power(importable = true, export = true), layout = @Layout(
+ tableLeftFixed = 3,
+ pageSize = 30))
+public class GithubTrendingRepo extends MetaModelVo {
+ @EruptField(views = @View(title = "名称"), edit = @Edit(title = "名称", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String name;
+ @EruptField(views = @View(title = "URL"), edit = @Edit(title = "URL", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String url;
+ @EruptField(views = @View(title = "全名"), edit = @Edit(title = "全名", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String fullName;
+
+ private String nodeId;
+ @EruptField(views = @View(title = "描述"), edit = @Edit(title = "描述", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String description;
+ @EruptField(views = @View(title = "fork数量"), edit = @Edit(title = "fork数量", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private int forksCount;
+ @EruptField(views = @View(title = "star数量"), edit = @Edit(title = "star数量", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private int stargazersCount;
+
+
+ @EruptField(views = @View(title = "主题"), edit = @Edit(title = "主题", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String topics;
+
+ @EruptField(views = @View(title = "语言"), edit = @Edit(title = "语言", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String language;
+
+
+ @EruptField(views = @View(title = "trendingDate"), edit = @Edit(title = "上榜日期", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private Date trendingDate;
+
+ @EruptField(views = @View(title = "周期"), edit = @Edit(title = "周期", type = EditType.INPUT, search = @Search, notNull = true, inputType = @InputType))
+ private String dateRange;
+}
diff --git a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/service/GithubService.java b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/service/GithubService.java
index c530d7f..348ff37 100644
--- a/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/service/GithubService.java
+++ b/fluent-erupts/fleunt-github/src/main/java/io/fluent/github/service/GithubService.java
@@ -14,4 +14,6 @@ public void saveUserStarredRepo(String userName,int page){
userService.saveUserStarredRepo(userName,page);
log.info("complete saved user starred repo");
}
+
+
}
diff --git a/fluent-erupts/fluent-bpm/README.md b/fluent-erupts/fluent-bpm/README.md
new file mode 100644
index 0000000..27f5612
--- /dev/null
+++ b/fluent-erupts/fluent-bpm/README.md
@@ -0,0 +1,12 @@
+
+- 个人办公: 待办事项、抄送传阅、办理历史、发起申请、申请历史、我的草稿
+
+- 内容管理: 公告、新闻
+
+- 组织管理:组织管理、用户管理、角色管理、 岗位管理。笔者十多年研发见过无数组织架构,它堪称最精简最完美的设计。
+
+- 流程管理: 表单表单设计、流程设计、流程实例管理、任务管理、系统对话框管理。(目前基于AgileBPM的商业组件,如果觉得不合适可切换为其他框架的流程模块,目前没有能入眼的)
+
+- 系统管理:字典分类管理、异常日志、系统资源、系统属性、常用脚本、短信邮件通知
+
+- 资产管理
\ No newline at end of file
diff --git a/modules/fluent-mocker/pom.xml b/fluent-erupts/fluent-bpm/pom.xml
similarity index 57%
rename from modules/fluent-mocker/pom.xml
rename to fluent-erupts/fluent-bpm/pom.xml
index c1fd962..e740d81 100644
--- a/modules/fluent-mocker/pom.xml
+++ b/fluent-erupts/fluent-bpm/pom.xml
@@ -5,12 +5,16 @@
4.0.0
io.fluent
- components
+ fluent-erupts
1.0-SNAPSHOT
- fluent-mocker
-
+ fluent-bpm
+
+ 21
+ 21
+ UTF-8
+
\ No newline at end of file
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/handlers/SqlTagFetchHandler.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/handlers/SqlTagFetchHandler.java
similarity index 97%
rename from fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/handlers/SqlTagFetchHandler.java
rename to fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/handlers/SqlTagFetchHandler.java
index 044f686..49c3f00 100644
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/handlers/SqlTagFetchHandler.java
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/handlers/SqlTagFetchHandler.java
@@ -1,4 +1,4 @@
-package io.fluentqa.base.handlers;
+package io.fluent.base.handlers;
import java.util.List;
import java.util.function.Supplier;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/ModelWithValidFlag.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/ModelWithValidFlag.java
similarity index 96%
rename from fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/ModelWithValidFlag.java
rename to fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/ModelWithValidFlag.java
index 4f6e8b7..52d898e 100644
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/ModelWithValidFlag.java
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/ModelWithValidFlag.java
@@ -1,4 +1,4 @@
-package io.fluentqa.base.model;
+package io.fluent.base.model;
import javax.persistence.MappedSuperclass;
import xyz.erupt.annotation.EruptField;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/ModelWithValidFlagVo.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/ModelWithValidFlagVo.java
similarity index 97%
rename from fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/ModelWithValidFlagVo.java
rename to fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/ModelWithValidFlagVo.java
index e93ded9..dcddd18 100644
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/ModelWithValidFlagVo.java
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/ModelWithValidFlagVo.java
@@ -1,4 +1,4 @@
-package io.fluentqa.base.model;
+package io.fluent.base.model;
import javax.persistence.MappedSuperclass;
import org.hibernate.annotations.DynamicInsert;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/NamedModelVO.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/NamedModelVO.java
similarity index 97%
rename from fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/NamedModelVO.java
rename to fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/NamedModelVO.java
index 89e28ec..f92a302 100644
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/NamedModelVO.java
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/NamedModelVO.java
@@ -1,4 +1,4 @@
-package io.fluentqa.base.model;
+package io.fluent.base.model;
import javax.persistence.MappedSuperclass;
import org.hibernate.annotations.DynamicInsert;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/NamedTimeStatusModel.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/NamedTimeStatusModel.java
similarity index 98%
rename from fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/NamedTimeStatusModel.java
rename to fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/NamedTimeStatusModel.java
index d29d492..fc6d038 100644
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/model/NamedTimeStatusModel.java
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/model/NamedTimeStatusModel.java
@@ -1,4 +1,4 @@
-package io.fluentqa.base.model;
+package io.fluent.base.model;
import java.time.LocalDate;
import javax.persistence.MappedSuperclass;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/package-info.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/package-info.java
new file mode 100644
index 0000000..f741592
--- /dev/null
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/package-info.java
@@ -0,0 +1 @@
+package io.fluent.base;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/proxies/AuditDataEnhancerProxy.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/proxies/AuditDataEnhancerProxy.java
similarity index 94%
rename from fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/proxies/AuditDataEnhancerProxy.java
rename to fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/proxies/AuditDataEnhancerProxy.java
index 2ede92d..31ff66d 100644
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/proxies/AuditDataEnhancerProxy.java
+++ b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluent/base/proxies/AuditDataEnhancerProxy.java
@@ -1,4 +1,4 @@
-package io.fluentqa.base.proxies;
+package io.fluent.base.proxies;
import java.time.LocalDateTime;
import org.springframework.stereotype.Component;
diff --git a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/package-info.java b/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/package-info.java
deleted file mode 100644
index 3bce169..0000000
--- a/fluent-erupts/fluent-erupts-base/src/main/java/io/fluentqa/base/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package io.fluentqa.base;
diff --git a/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceModel.java b/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceModel.java
index 463c0b6..a30b72a 100644
--- a/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceModel.java
+++ b/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceModel.java
@@ -1,7 +1,7 @@
package io.fluentqa.generator.model;
-import io.fluentqa.base.handlers.SqlTagFetchHandler;
-import io.fluentqa.base.model.ModelWithValidFlagVo;
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlagVo;
import io.fluentqa.generator.handlers.DataSourceTableSyncHandler;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
diff --git a/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceTableColumModel.java b/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceTableColumModel.java
index af89933..be40c77 100644
--- a/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceTableColumModel.java
+++ b/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/DataSourceTableColumModel.java
@@ -1,7 +1,7 @@
package io.fluentqa.generator.model;
-import io.fluentqa.base.handlers.SqlTagFetchHandler;
-import io.fluentqa.base.model.ModelWithValidFlag;
+import io.fluent.base.handlers.SqlTagFetchHandler;
+import io.fluent.base.model.ModelWithValidFlag;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Where;
diff --git a/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/SqlConfigEntity.java b/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/SqlConfigEntity.java
index 39a0717..3f5d4c4 100644
--- a/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/SqlConfigEntity.java
+++ b/fluent-erupts/fluent-generator/src/main/java/io/fluentqa/generator/model/SqlConfigEntity.java
@@ -1,6 +1,6 @@
package io.fluentqa.generator.model;
-import io.fluentqa.base.model.NamedModelVO;
+import io.fluent.base.model.NamedModelVO;
import lombok.Data;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
diff --git a/fluent-erupts/pom.xml b/fluent-erupts/pom.xml
index 66b425c..ccaf563 100644
--- a/fluent-erupts/pom.xml
+++ b/fluent-erupts/pom.xml
@@ -16,6 +16,7 @@
fluent-erupts-base
fluent-generator
fleunt-github
+ fluent-bpm
diff --git a/fluent-wrappers/fluent-excel/src/main/java/io/fluentqa/excel/ExcelReadWriter.java b/fluent-wrappers/fluent-excel/src/main/java/io/fluent/excel/ExcelReadWriter.java
similarity index 96%
rename from fluent-wrappers/fluent-excel/src/main/java/io/fluentqa/excel/ExcelReadWriter.java
rename to fluent-wrappers/fluent-excel/src/main/java/io/fluent/excel/ExcelReadWriter.java
index 83765cf..40aa141 100644
--- a/fluent-wrappers/fluent-excel/src/main/java/io/fluentqa/excel/ExcelReadWriter.java
+++ b/fluent-wrappers/fluent-excel/src/main/java/io/fluent/excel/ExcelReadWriter.java
@@ -1,4 +1,4 @@
-package io.fluentqa.excel;
+package io.fluent.excel;
import com.github.crab2died.ExcelUtils;
import com.github.crab2died.exceptions.Excel4JException;
diff --git a/fluent-wrappers/fluent-excel/src/main/java/io/fluent/excel/package-info.java b/fluent-wrappers/fluent-excel/src/main/java/io/fluent/excel/package-info.java
new file mode 100644
index 0000000..b27cea0
--- /dev/null
+++ b/fluent-wrappers/fluent-excel/src/main/java/io/fluent/excel/package-info.java
@@ -0,0 +1 @@
+package io.fluent.excel;
diff --git a/fluent-wrappers/fluent-excel/src/main/java/io/fluentqa/excel/package-info.java b/fluent-wrappers/fluent-excel/src/main/java/io/fluentqa/excel/package-info.java
deleted file mode 100644
index a033ad3..0000000
--- a/fluent-wrappers/fluent-excel/src/main/java/io/fluentqa/excel/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package io.fluentqa.excel;
diff --git a/fluent-wrappers/fluent-excel/src/test/java/io/fluentqa/excel/DemoExcelModel.java b/fluent-wrappers/fluent-excel/src/test/java/io/fluent/excel/DemoExcelModel.java
similarity index 92%
rename from fluent-wrappers/fluent-excel/src/test/java/io/fluentqa/excel/DemoExcelModel.java
rename to fluent-wrappers/fluent-excel/src/test/java/io/fluent/excel/DemoExcelModel.java
index 0cbbcc5..87dbadb 100644
--- a/fluent-wrappers/fluent-excel/src/test/java/io/fluentqa/excel/DemoExcelModel.java
+++ b/fluent-wrappers/fluent-excel/src/test/java/io/fluent/excel/DemoExcelModel.java
@@ -1,4 +1,4 @@
-package io.fluentqa.excel;
+package io.fluent.excel;
import com.github.crab2died.annotation.ExcelField;
import lombok.AllArgsConstructor;
diff --git a/fluent-wrappers/fluent-excel/src/test/java/io/fluentqa/excel/ExcelUtilsTest.java b/fluent-wrappers/fluent-excel/src/test/java/io/fluent/excel/ExcelUtilsTest.java
similarity index 96%
rename from fluent-wrappers/fluent-excel/src/test/java/io/fluentqa/excel/ExcelUtilsTest.java
rename to fluent-wrappers/fluent-excel/src/test/java/io/fluent/excel/ExcelUtilsTest.java
index 1742770..3da3361 100644
--- a/fluent-wrappers/fluent-excel/src/test/java/io/fluentqa/excel/ExcelUtilsTest.java
+++ b/fluent-wrappers/fluent-excel/src/test/java/io/fluent/excel/ExcelUtilsTest.java
@@ -1,4 +1,4 @@
-package io.fluentqa.excel;
+package io.fluent.excel;
import java.io.File;
import java.io.IOException;
diff --git a/fluent-wrappers/fluent-git/pom.xml b/fluent-wrappers/fluent-git/pom.xml
index 4d90fb4..3d13791 100644
--- a/fluent-wrappers/fluent-git/pom.xml
+++ b/fluent-wrappers/fluent-git/pom.xml
@@ -37,7 +37,11 @@
postgresql
${postgresql.version}
-
+
+ org.jsoup
+ jsoup
+ 1.17.2
+
diff --git a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/GithubUserService.java b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/GithubUserService.java
index e0ac806..84b8c87 100644
--- a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/GithubUserService.java
+++ b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/GithubUserService.java
@@ -1,14 +1,28 @@
package io.fluent.git.github;
-import static io.fluent.git.github.config.ConfigHolder.getGithubApiClient;
+import static io.fluent.git.github.config.ClientConfig.getGithubApiClient;
+import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jcabi.github.Github;
import com.jcabi.http.response.JsonResponse;
+import io.fluent.git.github.entity.GithubTrendingRepo;
+import io.fluent.git.github.enums.GithubDateRange;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import java.util.ArrayList;
+
import io.fluent.git.github.models.GithubRepoModel;
import io.fluent.git.github.repo.GithubDao;
import java.io.IOException;
import java.util.List;
+
+
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -49,7 +63,52 @@ private int saveIt(String userName, int page, int pageSize)
.as(JsonResponse.class);
List repos = JSONUtil.toList(result.body(), GithubRepoModel.class);
+
githubDao.saveAll(repos);
return repos.size();
}
+
+ public List getGithubTrendingRepos(String dateRange) {
+
+ try {
+ String url = String.format("https://github.com/trending?since=%s", dateRange);
+ var client = new OkHttpClient();
+ Request request = new Request.Builder()
+ .url(url)
+ .build();
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
+
+ Document doc = Jsoup.parse(response.body().string());
+ Elements repoElements = doc.select("article.Box-row");
+
+ List trendingRepos = new ArrayList<>();
+ for (Element repoElement : repoElements) {
+ String repoName = repoElement.selectXpath("h2").select("a").get(0).attr("href");
+ String description = repoElement.select("p.col-9").text();
+ String language = repoElement.select("span[itemprop=programmingLanguage]").text();
+ String stars = repoElement.select("a.Link--muted").first().text();
+ GithubTrendingRepo repo = new GithubTrendingRepo();
+ repo.setFullName(repoName);
+ repo.setUrl(StrUtil.join("","https://github.com",repoName));
+ repo.setDescription(description);
+ repo.setLanguages(language);
+ repo.setStargazersCount(Integer.parseInt(stars.replaceAll(",", "")));
+ trendingRepos.add(repo);
+ }
+
+ return trendingRepos;
+ }
+ } catch (IOException e) {
+ log.error("Error fetching trending repositories", e);
+ throw new RuntimeException("Failed to fetch trending repositories", e);
+ }
+ }
+
+ public void saveGithubTrendingRepo(){
+ for (GithubDateRange value : GithubDateRange.values()) {
+ List models = getGithubTrendingRepos(value.toString());
+ System.out.println(models);
+ }
+ }
}
diff --git a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/config/ConfigHolder.java b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/config/ClientConfig.java
similarity index 96%
rename from fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/config/ConfigHolder.java
rename to fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/config/ClientConfig.java
index f3a90d8..0ffd95a 100644
--- a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/config/ConfigHolder.java
+++ b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/config/ClientConfig.java
@@ -6,7 +6,7 @@
import io.fluent.quickdao.datasource.model.DataSourceSetting;
import io.github.cdimascio.dotenv.Dotenv;
-public class ConfigHolder {
+public class ClientConfig {
public static Dotenv dotenv = Dotenv.load();
diff --git a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubStarredRepo.java b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubStarredRepo.java
index 769b240..0d460f8 100644
--- a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubStarredRepo.java
+++ b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubStarredRepo.java
@@ -8,6 +8,8 @@ public class GithubStarredRepo {
private Long id;
private String name;
private String url;
+ @QuickDaoColumn(name = "html_url")
+ private String htmlUrl;
@QuickDaoColumn(name = "full_name")
private String fullName;
diff --git a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubTrendingRepo.java b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubTrendingRepo.java
new file mode 100644
index 0000000..bc0ef45
--- /dev/null
+++ b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/entity/GithubTrendingRepo.java
@@ -0,0 +1,43 @@
+package io.fluent.git.github.entity;
+
+import io.fluent.git.github.models.GithubRepoModel;
+import io.fluent.quickdao.annotations.QuickDaoColumn;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class GithubTrendingRepo {
+ private Long id;
+ @QuickDaoColumn(name = "name")
+ private String name;
+ @QuickDaoColumn(name = "trending_date")
+ private String url;
+ @QuickDaoColumn(name = "full_name")
+ private String fullName;
+
+ @QuickDaoColumn(name = "node_id")
+ private String nodeId;
+ @QuickDaoColumn(name = "description")
+ private String description;
+
+ @QuickDaoColumn(name = "forks_count")
+ private int forksCount;
+
+ @QuickDaoColumn(name = "stargazers_count")
+ private int stargazersCount;
+
+ @QuickDaoColumn(name = "topics")
+ private String topics;
+
+ @QuickDaoColumn(name = "languages")
+ private String languages;
+
+ @QuickDaoColumn(name = "date_range")
+ private String dateRange;
+
+ @QuickDaoColumn(name = "trending_date")
+ private Date trendingDate;
+
+
+}
diff --git a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/enums/GithubDateRange.java b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/enums/GithubDateRange.java
new file mode 100644
index 0000000..88e16d4
--- /dev/null
+++ b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/enums/GithubDateRange.java
@@ -0,0 +1,5 @@
+package io.fluent.git.github.enums;
+
+public enum GithubDateRange {
+ Daily,Weekly,Monthly
+}
diff --git a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/repo/GithubDao.java b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/repo/GithubDao.java
index 143936a..3717c62 100644
--- a/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/repo/GithubDao.java
+++ b/fluent-wrappers/fluent-git/src/main/java/io/fluent/git/github/repo/GithubDao.java
@@ -2,28 +2,47 @@
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
-import io.fluent.git.github.config.ConfigHolder;
+import io.fluent.git.github.config.ClientConfig;
import io.fluent.git.github.entity.GithubStarredRepo;
+import io.fluent.git.github.entity.GithubTrendingRepo;
import io.fluent.git.github.models.GithubRepoModel;
import io.fluent.quickdao.QuickDao;
+
+import java.util.Date;
import java.util.List;
+
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class GithubDao {
- private QuickDao dao = ConfigHolder.getDao();
+ private QuickDao dao = ClientConfig.getDao();
- public void save(GithubRepoModel model) {
- GithubStarredRepo entity = BeanUtil.copyProperties(model, GithubStarredRepo.class, "topics");
+ public void saveGithubStarredRepo(GithubRepoModel model) {
+ GithubStarredRepo entity = BeanUtil.copyProperties(model, GithubStarredRepo.class, "topics");
- entity.setTopics(StrUtil.join(",", model.getTopics()));
- dao.saveOrUpdate(entity, "github_starred_repo", "node_id");
- }
+ entity.setTopics(StrUtil.join(",", model.getTopics()));
+ dao.saveOrUpdate(entity, "github_starred_repo", "node_id");
+ }
+
+ public void saveGithubTrendingRepo(GithubTrendingRepo model) {
+ dao.saveOrUpdate(model, "github_trending_repo", "name");
+ }
- public void saveAll(List models) {
- for (GithubRepoModel model : models) {
- log.info("start save model : {}", model.getFullName());
- save(model);
+ public void saveAllGithubTrendingRepo(List models) {
+ var today = new Date();
+ for (GithubTrendingRepo model : models) {
+ log.info("start save model : {}", model.getFullName());
+ model.setTrendingDate(today);
+ saveGithubTrendingRepo(model);
+ }
}
- }
+
+ public void saveAll(List models) {
+ for (GithubRepoModel model : models) {
+ log.info("start save model : {}", model.getFullName());
+ saveGithubStarredRepo(model);
+ }
+ }
+
+
}
diff --git a/fluent-wrappers/fluent-git/src/test/java/io/fluent/git/github/GithubUserServiceTest.java b/fluent-wrappers/fluent-git/src/test/java/io/fluent/git/github/GithubUserServiceTest.java
index ce57529..12e0ab1 100644
--- a/fluent-wrappers/fluent-git/src/test/java/io/fluent/git/github/GithubUserServiceTest.java
+++ b/fluent-wrappers/fluent-git/src/test/java/io/fluent/git/github/GithubUserServiceTest.java
@@ -4,6 +4,7 @@
import com.jcabi.github.Github;
import com.jcabi.github.RtGithub;
import com.jcabi.http.response.JsonResponse;
+import io.fluent.git.github.enums.GithubDateRange;
import io.fluent.git.github.models.GithubRepoModel;
import io.github.cdimascio.dotenv.Dotenv;
import java.io.IOException;
@@ -16,6 +17,7 @@ public class GithubUserServiceTest {
String githubAccessToken = dotenv.get("GITHUB_ACCESS_TOKEN");
Github github = new RtGithub(githubAccessToken);
+ GithubUserService service = new GithubUserService();
@Test
public void createGithubClient() throws IOException {
@@ -48,4 +50,10 @@ public void testSaveGithubRepos() {
GithubUserService service = new GithubUserService();
service.saveUserStarredRepo("kennethreitz", 0);
}
+
+ @Test
+ public void testGetGithubTrendingRepos() {
+ var result = service.getGithubTrendingRepos(GithubDateRange.Daily.toString());
+ System.out.println(result);
+ }
}
diff --git a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpLogger.java b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpLogger.java
new file mode 100644
index 0000000..d2c4835
--- /dev/null
+++ b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpLogger.java
@@ -0,0 +1,41 @@
+package io.fluent.clients.base;
+
+import cn.hutool.core.util.StrUtil;
+import okhttp3.logging.HttpLoggingInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+public class HttpLogger implements HttpLoggingInterceptor.Logger {
+ private static final Marker MARKER = MarkerFactory.getMarker("OKHTTP");
+
+ private final Logger logger;
+
+ public HttpLogger() {
+ this.logger = LoggerFactory.getLogger(HttpLogger.class);
+ }
+
+ public HttpLogger(Logger logger) {
+ if (logger != null) {
+ this.logger = logger;
+ } else {
+ this.logger = LoggerFactory.getLogger(HttpLogger.class);
+ }
+ }
+
+ public HttpLogger(String logName) {
+
+ if (StrUtil.isBlank(logName)) {
+ this.logger = LoggerFactory.getLogger(HttpLogger.class);
+ } else {
+ this.logger = LoggerFactory.getLogger(logName);
+ }
+ }
+
+ @Override
+ public void log(String message) {
+
+ logger.debug(MARKER, message);
+ }
+}
\ No newline at end of file
diff --git a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpRequestModel.java b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpRequestModel.java
index 4129a34..fcb66e1 100644
--- a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpRequestModel.java
+++ b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/base/HttpRequestModel.java
@@ -47,6 +47,16 @@ public HttpRequestModel addQueryParams(String key, String value) {
return this;
}
+ public HttpRequestModel baseUrl(String baseUrl) {
+ this.baseUrl = baseUrl;
+ return this;
+ }
+
+ public HttpRequestModel urlPath(String urlPath) {
+ this.urlPath = urlPath;
+ return this;
+ }
+
public HttpRequestModel addHeader(String key, String value) {
this.headers.put(key, value);
return this;
diff --git a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientFactory.java b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientFactory.java
index a05f28d..419d90e 100644
--- a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientFactory.java
+++ b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientFactory.java
@@ -3,11 +3,13 @@
import static java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER;
import io.fluent.clients.base.HttpClientOption;
+
import java.net.CookieManager;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
+
import okhttp3.ConnectionPool;
import okhttp3.Credentials;
import okhttp3.JavaNetCookieJar;
@@ -16,48 +18,48 @@
public class HttpClientFactory {
- public OkHttpClient okHttpClient(HttpClientOption httpConfig) {
-
- ConnectionPool connectionPool =
- new ConnectionPool(
- httpConfig.getMaxIdleConnections(),
- httpConfig.getKeepAliveDuration(),
- TimeUnit.SECONDS);
-
- OkHttpClient.Builder builder =
- new OkHttpClient.Builder()
- .connectionPool(connectionPool)
- // 跳转由自己控制
- .followRedirects(false)
- .readTimeout(Duration.ofSeconds(httpConfig.getReadTimeout()))
- .connectTimeout(Duration.ofSeconds(httpConfig.getReadTimeout()));
-
- if (httpConfig.isCookie()) {
- CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
- builder.cookieJar(new JavaNetCookieJar(cookieManager));
- }
- // proxy
- if (httpConfig.isUseProxy()) {
- builder.proxy(
- new Proxy(
- httpConfig.getProxy().getType(),
- new InetSocketAddress(
- httpConfig.getProxy().getHost(), httpConfig.getProxy().getPort())));
- if (StringUtils.isNotBlank(httpConfig.getProxy().getPassword())) {
- builder.proxyAuthenticator(
- (route, response) -> {
- // 设置代理服务器账号密码
- String credential =
- Credentials.basic(
- httpConfig.getProxy().getUserName(), httpConfig.getProxy().getPassword());
- return response
- .request()
- .newBuilder()
- .header("Proxy-Authorization", credential)
- .build();
- });
- }
+ public OkHttpClient okHttpClient(HttpClientOption httpConfig) {
+
+ ConnectionPool connectionPool =
+ new ConnectionPool(
+ httpConfig.getMaxIdleConnections(),
+ httpConfig.getKeepAliveDuration(),
+ TimeUnit.SECONDS);
+
+ OkHttpClient.Builder builder =
+ new OkHttpClient.Builder()
+ .connectionPool(connectionPool)
+ // 跳转由自己控制
+ .followRedirects(false)
+ .readTimeout(Duration.ofSeconds(httpConfig.getReadTimeout()))
+ .connectTimeout(Duration.ofSeconds(httpConfig.getReadTimeout()));
+
+ if (httpConfig.isCookie()) {
+ CookieManager cookieManager = new CookieManager(null, ACCEPT_ORIGINAL_SERVER);
+ builder.cookieJar(new JavaNetCookieJar(cookieManager));
+ }
+ // proxy
+ if (httpConfig.isUseProxy()) {
+ builder.proxy(
+ new Proxy(
+ httpConfig.getProxy().getType(),
+ new InetSocketAddress(
+ httpConfig.getProxy().getHost(), httpConfig.getProxy().getPort())));
+ if (StringUtils.isNotBlank(httpConfig.getProxy().getPassword())) {
+ builder.proxyAuthenticator(
+ (route, response) -> {
+ // 设置代理服务器账号密码
+ String credential =
+ Credentials.basic(
+ httpConfig.getProxy().getUserName(), httpConfig.getProxy().getPassword());
+ return response
+ .request()
+ .newBuilder()
+ .header("Proxy-Authorization", credential)
+ .build();
+ });
+ }
+ }
+ return builder.build();
}
- return builder.build();
- }
}
diff --git a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientProcessor.java b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientProcessor.java
index 5713a3d..fe9a7be 100644
--- a/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientProcessor.java
+++ b/fluent-wrappers/fluent-httpclients/src/main/java/io/fluent/clients/factory/HttpClientProcessor.java
@@ -1,11 +1,19 @@
package io.fluent.clients.factory;
import io.fluent.clients.base.HttpClientOption;
+import io.fluent.clients.base.HttpException;
import io.fluent.clients.base.HttpRequestModel;
import java.io.IOException;
+
+import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Response;
+/**
+ * 1. setup processor
+ * 2. send request model
+ * 3. get response then handle response
+ */
public class HttpClientProcessor {
private HttpClientOption httpClientConfig;
@@ -29,4 +37,9 @@ public Response invoke(HttpRequestModel httpRequestModel) {
}
return response;
}
+ //TODO: implement async invoke
+ public Response asyncInvoke(HttpRequestModel httpRequestModel) {
+
+ throw new RuntimeException("Not implemented");
+ }
}
diff --git a/fluent-wrappers/fluent-httpclients/src/test/java/io/fluent/clients/factory/HttpClientFactoryTest.java b/fluent-wrappers/fluent-httpclients/src/test/java/io/fluent/clients/factory/HttpClientFactoryTest.java
index df97f58..37213da 100644
--- a/fluent-wrappers/fluent-httpclients/src/test/java/io/fluent/clients/factory/HttpClientFactoryTest.java
+++ b/fluent-wrappers/fluent-httpclients/src/test/java/io/fluent/clients/factory/HttpClientFactoryTest.java
@@ -1,144 +1,146 @@
-// package io.fluentqa.clients.factory;
+//package io.fluent.clients.factory;
//
-// import io.fluentqa.builtin.jsons.JSONUtils;
-// import io.fluentqa.clients.base.HttpClientOption;
-// import io.fluentqa.clients.base.HttpRequestModel;
-// import okhttp3.OkHttpClient;
-// import okhttp3.Request;
-// import okhttp3.RequestBody;
-// import okhttp3.Response;
-// import org.junit.jupiter.api.Test;
+//import cn.hutool.json.JSONUtil;
+//import io.fluent.clients.base.HttpClientOption;
+//import io.fluent.clients.base.HttpRequestModel;
+//import okhttp3.OkHttpClient;
+//import okhttp3.Request;
+//import okhttp3.RequestBody;
+//import okhttp3.Response;
+//import org.junit.jupiter.api.Test;
//
-// import java.io.IOException;
-// import java.nio.charset.StandardCharsets;
+//import java.io.IOException;
+//import java.nio.charset.StandardCharsets;
//
-// import static org.junit.jupiter.api.Assertions.*;
+//import static org.junit.jupiter.api.Assertions.*;
//
-// public class HttpClientFactoryTest {
-// HttpClientFactory factory = new HttpClientFactory();
-// HttpClientOption config = new HttpClientOption();
-// OkHttpClient client = factory.okHttpClient(config);
//
-// @Test
-// void test_OkHttpClient() {
+//public class HttpClientFactoryTest {
+// HttpClientFactory factory = new HttpClientFactory();
+// HttpClientOption config = new HttpClientOption();
// OkHttpClient client = factory.okHttpClient(config);
-// assertNotNull(client);
-// }
-//
-// @Test
-// void test_OkHttpClient_get() {
-// Request request = new Request.Builder()
-// .url("https://www.baidu.com").build();
-// callApi(request);
-// }
-//
-// String tokenRespones = "{\"user_info\":{\"id\":1,\"name\":\"prest\",\"username\":\"prest\"," +
-// "\"metadata\":null},\"token\":" +
-//
-// "\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySW5mbyI6eyJpZCI6MSwibWV0YWRhdGEiOm51bGwsIm5hbWUiOiJwcmVzdCIsInVzZXJuYW1lIjoicHJlc3QifSwiZXhwIjoxNjgzNTY2MTMzLCJuYmYiOjE2ODM1NDQ1MzN9.4xSD5TiEnauLrLwLRbEHxwK6lduXIjvwijiPLXvYdYo\"}\n";
-//
-// @Test
-// void testPrestdGetSchema() {
-// Request request = new Request.Builder().url("http://127.0.0.1:3000/auth")
-// .post(RequestBody.create("{\"username\": \"prest\", \"password\": \"prest\"}"
-// .getBytes(StandardCharsets.UTF_8))).build();
-// Response response = null;
-// callApi(request);
-// }
-//
-// private void callApi(Request request) {
-// Response response;
-// try {
-// response = client.newCall(request).execute();
-// System.out.println(response.body().string());
-// } catch (IOException e) {
-// throw new RuntimeException(e);
+//
+// @Test
+// void test_OkHttpClient() {
+// OkHttpClient client = factory.okHttpClient(config);
+// assertNotNull(client);
+// }
+//
+// @Test
+// void test_OkHttpClient_get() {
+// Request request = new Request.Builder()
+// .url("https://www.baidu.com").build();
+// callApi(request);
+// }
+//
+// String tokenRespones = "{\"user_info\":{\"id\":1,\"name\":\"prest\",\"username\":\"prest\"," +
+// "\"metadata\":null},\"token\":" +
+//
+// "\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySW5mbyI6eyJpZCI6MSwibWV0YWRhdGEiOm51bGwsIm5hbWUiOiJwcmVzdCIsInVzZXJuYW1lIjoicHJlc3QifSwiZXhwIjoxNjgzNTY2MTMzLCJuYmYiOjE2ODM1NDQ1MzN9.4xSD5TiEnauLrLwLRbEHxwK6lduXIjvwijiPLXvYdYo\"}\n";
+//
+// @Test
+// void testPrestdGetSchema() {
+// Request request = new Request.Builder().url("http://127.0.0.1:3000/auth")
+// .post(RequestBody.create("{\"username\": \"prest\", \"password\": \"prest\"}"
+// .getBytes(StandardCharsets.UTF_8))).build();
+// Response response = null;
+// callApi(request);
+// }
+//
+// private void callApi(Request request) {
+// Response response;
+// try {
+// response = client.newCall(request).execute();
+// System.out.println(response.body().string());
+// } catch (IOException e) {
+// throw new RuntimeException(e);
+// }
+// }
+//
+// String baseUrl = "http://127.0.0.1:3000";
+// //Authorization: Bearer {TOKEN}
+// String auth = "auth";
+// String show_url = "/show/{DATABASE}/{SCHEMA}/{TABLE}";
+//
+// /**
+// * Endpoints Description
+// * /_health Health check endpoint
+// * /databases List all databases
+// * /schemas List all schemas
+// * /tables List all tables
+// * /show/{DATABASE}/{SCHEMA}/{TABLE} Lists table structure - all fields contained in the table
+// * /{DATABASE}/{SCHEMA} Lists table tables - find by schema
+// * /{DATABASE}/{SCHEMA}/{TABLE} List all rows, find by database, schema and table
+// * /{DATABASE}/{SCHEMA}/{VIEW} List all rows, find by database, schema and view
+// *
+// * POST:
+// * /{DATABASE}/{SCHEMA}/{TABLE}
+// * {
+// * "FIELD1": "string value",
+// * "FIELD2": 1234567890
+// * }
+// *
+// * PATCH/PUT:
+// * /{DATABASE}/{SCHEMA}/{TABLE}?{FIELD NAME}={VALUE}
+// * {
+// * "FIELD1": "string value",
+// * "FIELD2": 1234567890,
+// * "ARRAYFIELD": ["value 1","value 2"]
+// * }
+// * DELETE:
+// * /{DATABASE}/{SCHEMA}/{TABLE}?{FIELD NAME}={VALUE}
+// */
+// @Test
+// void testprestdGetDatabases() {
+// prestdQueryService("databases");
+// prestdQueryService("schemas");
+// prestdQueryService("tables");
+// }
+//
+// void prestdQueryService(String serviceName) {
+// String token = JSONUtil.parse(tokenRespones).getByPath("token").toString();
+// Request request = new Request.Builder().url("http://127.0.0.1:3000/" + serviceName)
+// .addHeader("Authorization", "Bearer %s".formatted(token))
+// .get().build();
+// callApi(request);
+// }
+//
+// //supabase postrest invocation
+// @Test
+// void querySupabaseService() {
+// String baseUrl = "http://localhost:54321/rest/v1/users";
+// String serviceKey
+// = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU";
+// String apiKey
+// = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0";
+// Request request = new Request.Builder().url(baseUrl)
+// .addHeader("Authorization", "Bearer %s".formatted(serviceKey))
+// .addHeader("apikey", apiKey)
+// .get().build();
+// callApi(request);
+// }
+//
+// @Test
+// void functionCall() {
+// String baseUrl =
+// "http://localhost:54321/rest/v1/rpc/get_key_by_email?in_email=test_1@163.com";
+// String serviceKey
+// = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU";
+// String apiKey
+// = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0";
+// Request request = new Request.Builder().url(baseUrl)
+// .addHeader("Authorization", "Bearer %s".formatted(serviceKey))
+// .addHeader("apikey", apiKey)
+// .get().build();
+// callApi(request);
+// }
+//
+// @Test
+// void testHttpProcessor() {
+// HttpRequestModel request = new HttpRequestModel();
+// HttpClientProcessor processor = new HttpClientProcessor();
+// processor.init();
+// processor.invoke(request);
+//
// }
-// }
-//
-// String baseUrl = "http://127.0.0.1:3000";
-// //Authorization: Bearer {TOKEN}
-// String auth="auth";
-// String show_url="/show/{DATABASE}/{SCHEMA}/{TABLE}";
-//
-// /**
-// * Endpoints Description
-// * /_health Health check endpoint
-// * /databases List all databases
-// * /schemas List all schemas
-// * /tables List all tables
-// * /show/{DATABASE}/{SCHEMA}/{TABLE} Lists table structure - all fields contained in the table
-// * /{DATABASE}/{SCHEMA} Lists table tables - find by schema
-// * /{DATABASE}/{SCHEMA}/{TABLE} List all rows, find by database, schema and table
-// * /{DATABASE}/{SCHEMA}/{VIEW} List all rows, find by database, schema and view
-// *
-// * POST:
-// * /{DATABASE}/{SCHEMA}/{TABLE}
-// * {
-// * "FIELD1": "string value",
-// * "FIELD2": 1234567890
-// * }
-// *
-// * PATCH/PUT:
-// * /{DATABASE}/{SCHEMA}/{TABLE}?{FIELD NAME}={VALUE}
-// * {
-// * "FIELD1": "string value",
-// * "FIELD2": 1234567890,
-// * "ARRAYFIELD": ["value 1","value 2"]
-// * }
-// * DELETE:
-// * /{DATABASE}/{SCHEMA}/{TABLE}?{FIELD NAME}={VALUE}
-// */
-// @Test
-// void testprestdGetDatabases() {
-// prestdQueryService("databases");
-// prestdQueryService("schemas");
-// prestdQueryService("tables");
-// }
-//
-// void prestdQueryService(String serviceName){
-// String token = JSONUtils.parse(tokenRespones).getByPath("token").toString();
-// Request request = new Request.Builder().url("http://127.0.0.1:3000/"+serviceName)
-// .addHeader("Authorization", "Bearer %s".formatted(token))
-// .get().build();
-// callApi(request);
-// }
-// //supabase postrest invocation
-// @Test
-// void querySupabaseService(){
-// String baseUrl = "http://localhost:54321/rest/v1/users";
-// String serviceKey
-// ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU";
-// String apiKey
-// ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0";
-// Request request = new Request.Builder().url(baseUrl)
-// .addHeader("Authorization", "Bearer %s".formatted(serviceKey))
-// .addHeader("apikey", apiKey)
-// .get().build();
-// callApi(request);
-// }
-//
-// @Test
-// void functionCall(){
-// String baseUrl =
-// "http://localhost:54321/rest/v1/rpc/get_key_by_email?in_email=test_1@163.com";
-// String serviceKey
-// ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU";
-// String apiKey
-// ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0";
-// Request request = new Request.Builder().url(baseUrl)
-// .addHeader("Authorization", "Bearer %s".formatted(serviceKey))
-// .addHeader("apikey", apiKey)
-// .get().build();
-// callApi(request);
-// }
-//
-// @Test
-// void testHttpProcessor(){
-// HttpRequestModel request = new HttpRequestModel();
-// HttpClientProcessor processor = new HttpClientProcessor();
-// processor.init();
-// processor.invoke(request);
-//
-// }
-// }
+//}
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/BasicAuthentication.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/BasicAuthentication.java
similarity index 91%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/BasicAuthentication.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/BasicAuthentication.java
index d41aa52..d8d2eeb 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/BasicAuthentication.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/BasicAuthentication.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
public class BasicAuthentication {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/CacheConfig.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/CacheConfig.java
similarity index 93%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/CacheConfig.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/CacheConfig.java
index 47ff8ab..c28ac13 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/CacheConfig.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/CacheConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
public class CacheConfig {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/CommentMappingConfig.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/CommentMappingConfig.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/CommentMappingConfig.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/CommentMappingConfig.java
index 4c77242..182e487 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/CommentMappingConfig.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/CommentMappingConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
public class CommentMappingConfig {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/Context.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/Context.java
similarity index 57%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/Context.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/Context.java
index e5b8292..e07e14d 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/Context.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/Context.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
public enum Context {
SOURCE,
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/DescriptionMappingConfig.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/DescriptionMappingConfig.java
similarity index 94%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/DescriptionMappingConfig.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/DescriptionMappingConfig.java
index 51e30eb..247ae3e 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/DescriptionMappingConfig.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/DescriptionMappingConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
public class DescriptionMappingConfig {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraConnectionProperties.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraConnectionProperties.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraConnectionProperties.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraConnectionProperties.java
index ce0c4bc..aee16fb 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraConnectionProperties.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraConnectionProperties.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
import java.io.File;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraProjectSync.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraProjectSync.java
similarity index 99%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraProjectSync.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraProjectSync.java
index cfaa299..d57b459 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraProjectSync.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraProjectSync.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
import java.net.URL;
import java.util.Arrays;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraSyncConfig.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraSyncConfig.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraSyncConfig.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraSyncConfig.java
index bf6841c..1503031 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/JiraSyncConfig.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/JiraSyncConfig.java
@@ -1,6 +1,7 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
+
+import io.fluent.jira.domain.JiraProject;
-import io.fluentqa.jira.domain.JiraProject;
import java.util.LinkedHashMap;
import java.util.Map;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/TransitionConfig.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/TransitionConfig.java
similarity index 96%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/TransitionConfig.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/TransitionConfig.java
index 91c8271..ad98666 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/config/TransitionConfig.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/config/TransitionConfig.java
@@ -1,7 +1,7 @@
-package io.fluentqa.jira.config;
+package io.fluent.jira.config;
-import io.fluentqa.jira.domain.JiraIssue;
-import io.fluentqa.jira.domain.JiraIssueType;
+import io.fluent.jira.domain.JiraIssue;
+import io.fluent.jira.domain.JiraIssueType;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraChangeLog.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraChangeLog.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraChangeLog.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraChangeLog.java
index f6dd3c7..706a9b1 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraChangeLog.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraChangeLog.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComment.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComment.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComment.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComment.java
index 17c5e0b..4757e94 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComment.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComment.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.ZonedDateTime;
@@ -11,10 +11,10 @@ public class JiraComment extends JiraIdResource {
private String body;
- @JsonFormat(pattern = JiraResource.JIRA_DATE_FORMAT)
+ @JsonFormat(pattern = JIRA_DATE_FORMAT)
private ZonedDateTime created;
- @JsonFormat(pattern = JiraResource.JIRA_DATE_FORMAT)
+ @JsonFormat(pattern = JIRA_DATE_FORMAT)
private ZonedDateTime updated;
public JiraComment() {}
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComments.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComments.java
similarity index 96%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComments.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComments.java
index 1f9cb07..c047fcd 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComments.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComments.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComponent.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComponent.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComponent.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComponent.java
index 71a9174..89dcad2 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComponent.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComponent.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraComponent extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComponentsList.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComponentsList.java
similarity index 82%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComponentsList.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComponentsList.java
index 53549ac..e3d84be 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraComponentsList.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraComponentsList.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraField.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraField.java
similarity index 94%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraField.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraField.java
index f0d772c..a7016ac 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraField.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraField.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraField extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldList.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldList.java
similarity index 85%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldList.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldList.java
index 5ec98a4..12826c0 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldList.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldList.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldSchema.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldSchema.java
similarity index 95%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldSchema.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldSchema.java
index 4abe18e..ac6a3da 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldSchema.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldSchema.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldsBean.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldsBean.java
similarity index 94%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldsBean.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldsBean.java
index 171dd90..c5a7137 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldsBean.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldsBean.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.util.Set;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldsUpdate.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldsUpdate.java
similarity index 98%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldsUpdate.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldsUpdate.java
index 6326d23..c1c73f3 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFieldsUpdate.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFieldsUpdate.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFilterResult.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFilterResult.java
similarity index 89%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFilterResult.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFilterResult.java
index 3272532..6a415c3 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraFilterResult.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraFilterResult.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIdResource.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIdResource.java
similarity index 91%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIdResource.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIdResource.java
index a6a33e8..4ef4f82 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIdResource.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIdResource.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public abstract class JiraIdResource extends JiraResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssue.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssue.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssue.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssue.java
index 2a95a3e..408989d 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssue.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssue.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueFields.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueFields.java
similarity index 99%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueFields.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueFields.java
index 4df5048..ffcd374 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueFields.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueFields.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueHistoryEntry.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueHistoryEntry.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueHistoryEntry.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueHistoryEntry.java
index 7196b51..74ee3f8 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueHistoryEntry.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueHistoryEntry.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueHistoryItem.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueHistoryItem.java
similarity index 98%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueHistoryItem.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueHistoryItem.java
index 9d6c32b..a91d1d6 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueHistoryItem.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueHistoryItem.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueStatus.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueStatus.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueStatus.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueStatus.java
index cbe49d7..b3c058c 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueStatus.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueStatus.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraIssueStatus extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueType.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueType.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueType.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueType.java
index a4d4c9c..b116c0e 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueType.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueType.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraIssueType extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueUpdate.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueUpdate.java
similarity index 97%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueUpdate.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueUpdate.java
index ba10c05..1846d78 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraIssueUpdate.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraIssueUpdate.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLinkIcon.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLinkIcon.java
similarity index 92%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLinkIcon.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLinkIcon.java
index 2c2f9f0..5c48b13 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLinkIcon.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLinkIcon.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.net.URL;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLoginRequest.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLoginRequest.java
similarity index 95%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLoginRequest.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLoginRequest.java
index ce330c9..6a101f8 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLoginRequest.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLoginRequest.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLoginResponse.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLoginResponse.java
similarity index 90%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLoginResponse.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLoginResponse.java
index 1e1676e..333ded5 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraLoginResponse.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraLoginResponse.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraNamedBean.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraNamedBean.java
similarity index 84%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraNamedBean.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraNamedBean.java
index 679ccec..b92e45f 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraNamedBean.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraNamedBean.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public interface JiraNamedBean {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraNamedResource.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraNamedResource.java
similarity index 93%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraNamedResource.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraNamedResource.java
index 2ab329e..b8a0ef7 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraNamedResource.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraNamedResource.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.util.Objects;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraPriority.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraPriority.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraPriority.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraPriority.java
index db412cb..93a1027 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraPriority.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraPriority.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraPriority extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraPriorityList.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraPriorityList.java
similarity index 85%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraPriorityList.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraPriorityList.java
index b652794..84bb255 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraPriorityList.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraPriorityList.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraProject.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraProject.java
similarity index 96%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraProject.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraProject.java
index 44ef64f..1f57ddd 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraProject.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraProject.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.util.List;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraProjectsList.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraProjectsList.java
similarity index 81%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraProjectsList.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraProjectsList.java
index dba3939..76f6aa1 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraProjectsList.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraProjectsList.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLink.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLink.java
similarity index 95%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLink.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLink.java
index b6f674f..bc9c9a5 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLink.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLink.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.net.MalformedURLException;
import java.net.URL;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLinkObject.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLinkObject.java
similarity index 95%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLinkObject.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLinkObject.java
index c0bd5cc..eab71d9 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLinkObject.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLinkObject.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.net.URL;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLinks.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLinks.java
similarity index 85%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLinks.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLinks.java
index 8cce824..d809f9b 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraRemoteLinks.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraRemoteLinks.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResolution.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResolution.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResolution.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResolution.java
index 5868dd7..27b7823 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResolution.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResolution.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraResolution extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResolutionList.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResolutionList.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResolutionList.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResolutionList.java
index 3d7d404..b4997d8 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResolutionList.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResolutionList.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResource.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResource.java
similarity index 92%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResource.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResource.java
index 3361877..7bf1e91 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraResource.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraResource.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraSearchResult.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraSearchResult.java
similarity index 96%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraSearchResult.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraSearchResult.java
index 8eb7277..900d1f9 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraSearchResult.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraSearchResult.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.List;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraServerInfo.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraServerInfo.java
similarity index 95%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraServerInfo.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraServerInfo.java
index 3e63647..14f4d52 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraServerInfo.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraServerInfo.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraServerInfo extends JiraResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraSession.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraSession.java
similarity index 93%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraSession.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraSession.java
index 2e11c79..a368178 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraSession.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraSession.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraTransition.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraTransition.java
similarity index 94%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraTransition.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraTransition.java
index 32da31a..85c5498 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraTransition.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraTransition.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraTransitions.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraTransitions.java
similarity index 94%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraTransitions.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraTransitions.java
index 23c970f..56ed8fe 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraTransitions.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraTransitions.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.io.Serializable;
import java.util.List;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraUser.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraUser.java
similarity index 94%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraUser.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraUser.java
index 96154d5..2e408a6 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraUser.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraUser.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraUser extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraVersion.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraVersion.java
similarity index 86%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraVersion.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraVersion.java
index 4133ad0..a3d9f7f 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraVersion.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraVersion.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public class JiraVersion extends JiraNamedResource {
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraVersionsList.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraVersionsList.java
similarity index 81%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraVersionsList.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraVersionsList.java
index 075c654..fff280b 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/JiraVersionsList.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/JiraVersionsList.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/WellKnownCustomFieldType.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/WellKnownCustomFieldType.java
similarity index 96%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/WellKnownCustomFieldType.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/WellKnownCustomFieldType.java
index 63c2718..c0c3fb6 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/WellKnownCustomFieldType.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/WellKnownCustomFieldType.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
public enum WellKnownCustomFieldType {
LABELS("com.atlassian.jira.plugin.system.customfieldtypes:labels"),
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/WellKnownJiraField.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/WellKnownJiraField.java
similarity index 96%
rename from fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/WellKnownJiraField.java
rename to fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/WellKnownJiraField.java
index c45e7e1..e0e1d97 100644
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/domain/WellKnownJiraField.java
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/domain/WellKnownJiraField.java
@@ -1,4 +1,4 @@
-package io.fluentqa.jira.domain;
+package io.fluent.jira.domain;
import de.cronn.reflection.util.PropertyGetter;
import de.cronn.reflection.util.PropertyUtils;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/package-info.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/package-info.java
new file mode 100644
index 0000000..c642f78
--- /dev/null
+++ b/fluent-wrappers/fluent-jira/src/main/java/io/fluent/jira/package-info.java
@@ -0,0 +1 @@
+package io.fluent.jira;
diff --git a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/package-info.java b/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/package-info.java
deleted file mode 100644
index 4c96b8f..0000000
--- a/fluent-wrappers/fluent-jira/src/main/java/io/fluentqa/jira/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package io.fluentqa.jira;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapAccessor.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapAccessor.java
similarity index 87%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapAccessor.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapAccessor.java
index aefed58..81ec664 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapAccessor.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapAccessor.java
@@ -1,7 +1,8 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
+
+import io.fluent.mindmap.freemind.FreeMindTransformer;
+import io.fluent.mindmap.xmind.XmindTransformer;
-import io.fluentqa.mindmap.freemind.FreeMindTransformer;
-import io.fluentqa.mindmap.xmind.XmindTransformer;
import java.util.List;
public class MindMapAccessor {
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapConvertConfig.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapConvertConfig.java
similarity index 92%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapConvertConfig.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapConvertConfig.java
index 05e5b64..7cf09ab 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapConvertConfig.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapConvertConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import java.util.ArrayList;
import java.util.List;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapPath.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapPath.java
similarity index 94%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapPath.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapPath.java
index 861f6dc..b3cd0bb 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapPath.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapPath.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import java.util.LinkedList;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapPathRecord.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapPathRecord.java
similarity index 98%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapPathRecord.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapPathRecord.java
index c0e7d12..727a88c 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapPathRecord.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapPathRecord.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import cn.hutool.core.bean.BeanUtil;
import io.fluent.builtin.meta.ReflectionUtils;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapTransformer.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapTransformer.java
similarity index 90%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapTransformer.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapTransformer.java
index 16477f6..13fa297 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindMapTransformer.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindMapTransformer.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import java.util.List;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindmapTypeEnum.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindmapTypeEnum.java
similarity index 94%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindmapTypeEnum.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindmapTypeEnum.java
index 0e8dc1b..11818f1 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/MindmapTypeEnum.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/MindmapTypeEnum.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import io.fluent.builtin.JavaProjectFileUtils;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/NodeLevel.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/NodeLevel.java
similarity index 84%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/NodeLevel.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/NodeLevel.java
index 267af71..e8bf9ce 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/api/NodeLevel.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/api/NodeLevel.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import java.lang.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/exception/MindMapException.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/exception/MindMapException.java
similarity index 92%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/exception/MindMapException.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/exception/MindMapException.java
index 6ddf5ff..4b026e3 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/exception/MindMapException.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/exception/MindMapException.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.exception;
+package io.fluent.mindmap.exception;
public class MindMapException extends RuntimeException {
public MindMapException() {}
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/FreeMindNode.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/FreeMindNode.java
similarity index 76%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/FreeMindNode.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/FreeMindNode.java
index a2cb3e2..31c0a57 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/FreeMindNode.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/FreeMindNode.java
@@ -1,7 +1,7 @@
-package io.fluentqa.mindmap.freemind;
+package io.fluent.mindmap.freemind;
-import io.fluentqa.mindmap.api.MindMapPath;
-import io.fluentqa.mindmap.freemind.model.Node;
+import io.fluent.mindmap.api.MindMapPath;
+import io.fluent.mindmap.freemind.model.Node;
public class FreeMindNode extends MindMapPath {
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/FreeMindTransformer.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/FreeMindTransformer.java
similarity index 88%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/FreeMindTransformer.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/FreeMindTransformer.java
index c994778..0f6746c 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/FreeMindTransformer.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/FreeMindTransformer.java
@@ -1,12 +1,12 @@
-package io.fluentqa.mindmap.freemind;
+package io.fluent.mindmap.freemind;
import io.fluent.builtin.XmlUtils;
-import io.fluentqa.mindmap.api.MindMapConvertConfig;
-import io.fluentqa.mindmap.api.MindMapPath;
-import io.fluentqa.mindmap.api.MindMapPathRecord;
-import io.fluentqa.mindmap.api.MindMapTransformer;
-import io.fluentqa.mindmap.freemind.model.Map;
-import io.fluentqa.mindmap.freemind.model.Node;
+import io.fluent.mindmap.api.MindMapConvertConfig;
+import io.fluent.mindmap.api.MindMapPath;
+import io.fluent.mindmap.api.MindMapPathRecord;
+import io.fluent.mindmap.api.MindMapTransformer;
+import io.fluent.mindmap.freemind.model.Map;
+import io.fluent.mindmap.freemind.model.Node;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Arrowlink.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Arrowlink.java
similarity index 99%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Arrowlink.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Arrowlink.java
index 4e29899..472c39e 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Arrowlink.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Arrowlink.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Attribute.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Attribute.java
similarity index 97%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Attribute.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Attribute.java
index beabd13..4d8c3e3 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Attribute.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Attribute.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/AttributeLayout.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/AttributeLayout.java
similarity index 97%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/AttributeLayout.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/AttributeLayout.java
index 4b8836e..8f96380 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/AttributeLayout.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/AttributeLayout.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
import java.math.BigInteger;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Cloud.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Cloud.java
similarity index 96%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Cloud.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Cloud.java
index f2cfc2a..0dc2343 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Cloud.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Cloud.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Edge.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Edge.java
similarity index 98%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Edge.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Edge.java
index 6719d30..10db299 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Edge.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Edge.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Font.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Font.java
similarity index 98%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Font.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Font.java
index 34bc2c1..b4dba65 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Font.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Font.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
import java.math.BigInteger;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Hook.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Hook.java
similarity index 98%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Hook.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Hook.java
index f6930c0..7f33895 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Hook.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Hook.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Html.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Html.java
similarity index 97%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Html.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Html.java
index 5b9a44f..f7fec81 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Html.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Html.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Icon.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Icon.java
similarity index 96%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Icon.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Icon.java
index f50b327..6751303 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Icon.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Icon.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Linktarget.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Linktarget.java
similarity index 99%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Linktarget.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Linktarget.java
index 17b25c0..d9b48c0 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Linktarget.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Linktarget.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Map.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Map.java
similarity index 97%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Map.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Map.java
index 62af792..5448d3b 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Map.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Map.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Node.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Node.java
similarity index 99%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Node.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Node.java
index 4f97a80..c119228 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Node.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Node.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
import jakarta.xml.bind.annotation.adapters.CollapsedStringAdapter;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/ObjectFactory.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/ObjectFactory.java
similarity index 98%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/ObjectFactory.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/ObjectFactory.java
index efc3dd1..9450b5f 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/ObjectFactory.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/ObjectFactory.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.XmlRegistry;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Parameters.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Parameters.java
similarity index 99%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Parameters.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Parameters.java
index a639fbb..960c7fe 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Parameters.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Parameters.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
import java.math.BigInteger;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Richcontent.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Richcontent.java
similarity index 97%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Richcontent.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Richcontent.java
index 0e91af4..bd2dec3 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Richcontent.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Richcontent.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.*;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Text.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Text.java
similarity index 95%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Text.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Text.java
index d6e535f..7f0e79a 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/freemind/model/Text.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/freemind/model/Text.java
@@ -5,7 +5,7 @@
// 生成时间: 2022.09.23 时间 08:46:06 PM CST
//
-package io.fluentqa.mindmap.freemind.model;
+package io.fluent.mindmap.freemind.model;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/package-info.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/package-info.java
new file mode 100644
index 0000000..c0f43e5
--- /dev/null
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/package-info.java
@@ -0,0 +1 @@
+package io.fluent.mindmap;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XMindNode.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XMindNode.java
similarity index 51%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XMindNode.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XMindNode.java
index 45b8b42..e811f79 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XMindNode.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XMindNode.java
@@ -1,7 +1,7 @@
-package io.fluentqa.mindmap.xmind;
+package io.fluent.mindmap.xmind;
-import io.fluentqa.mindmap.api.MindMapPath;
-import io.fluentqa.mindmap.xmind.model.Attached;
+import io.fluent.mindmap.xmind.model.Attached;
+import io.fluent.mindmap.api.MindMapPath;
public class XMindNode extends MindMapPath implements Cloneable {
public XMindNode(Attached root) {
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XMindUtil.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XMindUtil.java
similarity index 94%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XMindUtil.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XMindUtil.java
index b78516a..145156d 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XMindUtil.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XMindUtil.java
@@ -1,11 +1,12 @@
-package io.fluentqa.mindmap.xmind;
+package io.fluent.mindmap.xmind;
import cn.hutool.core.compress.ZipReader;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
-import io.fluentqa.mindmap.exception.MindMapException;
-import io.fluentqa.mindmap.xmind.model.XmindRawData;
+import io.fluent.mindmap.xmind.model.XmindRawData;
+import io.fluent.mindmap.exception.MindMapException;
+
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XmindTransformer.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XmindTransformer.java
similarity index 88%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XmindTransformer.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XmindTransformer.java
index f5ef381..5555b88 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/XmindTransformer.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/XmindTransformer.java
@@ -1,13 +1,14 @@
-package io.fluentqa.mindmap.xmind;
+package io.fluent.mindmap.xmind;
import cn.hutool.json.JSONUtil;
-import io.fluentqa.mindmap.api.MindMapConvertConfig;
-import io.fluentqa.mindmap.api.MindMapPath;
-import io.fluentqa.mindmap.api.MindMapPathRecord;
-import io.fluentqa.mindmap.api.MindMapTransformer;
-import io.fluentqa.mindmap.xmind.model.Attached;
-import io.fluentqa.mindmap.xmind.model.JsonRootBean;
-import io.fluentqa.mindmap.xmind.model.XmindRawData;
+import io.fluent.mindmap.xmind.model.Attached;
+import io.fluent.mindmap.xmind.model.JsonRootBean;
+import io.fluent.mindmap.xmind.model.XmindRawData;
+import io.fluent.mindmap.api.MindMapConvertConfig;
+import io.fluent.mindmap.api.MindMapPath;
+import io.fluent.mindmap.api.MindMapPathRecord;
+import io.fluent.mindmap.api.MindMapTransformer;
+
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Attached.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Attached.java
similarity index 83%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Attached.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Attached.java
index d39006d..fdb5244 100755
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Attached.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Attached.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import java.util.List;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Children.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Children.java
similarity index 73%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Children.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Children.java
index 96a5cb5..780973a 100755
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Children.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Children.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import java.util.List;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Comments.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Comments.java
similarity index 76%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Comments.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Comments.java
index 72b7b70..875a00b 100755
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Comments.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Comments.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/JsonRootBean.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/JsonRootBean.java
similarity index 76%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/JsonRootBean.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/JsonRootBean.java
index 20e984d..08ac87a 100755
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/JsonRootBean.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/JsonRootBean.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Notes.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Notes.java
similarity index 65%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Notes.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Notes.java
index c563e3d..ab40ce6 100755
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/Notes.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/Notes.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/RootTopic.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/RootTopic.java
similarity index 83%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/RootTopic.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/RootTopic.java
index 53dcbe9..5333dc5 100755
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/RootTopic.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/RootTopic.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import java.util.List;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/XmindRawData.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/XmindRawData.java
similarity index 96%
rename from fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/XmindRawData.java
rename to fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/XmindRawData.java
index 2761267..7009dc5 100644
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/xmind/model/XmindRawData.java
+++ b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluent/mindmap/xmind/model/XmindRawData.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.xmind.model;
+package io.fluent.mindmap.xmind.model;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
diff --git a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/package-info.java b/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/package-info.java
deleted file mode 100644
index 3ce5b18..0000000
--- a/fluent-wrappers/fluent-mindmap/src/main/java/io/fluentqa/mindmap/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package io.fluentqa.mindmap;
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBean.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBean.java
similarity index 89%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBean.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBean.java
index 36d160b..03390f0 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBean.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBean.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBeanConfig.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBeanConfig.java
similarity index 94%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBeanConfig.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBeanConfig.java
index 0e33039..c35e198 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBeanConfig.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBeanConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
public class DemoBeanConfig {
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBeanWOLevel.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBeanWOLevel.java
similarity index 86%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBeanWOLevel.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBeanWOLevel.java
index 77b9a7d..a889473 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/DemoBeanWOLevel.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/DemoBeanWOLevel.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import lombok.Data;
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/MindMapAccessorTest.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/MindMapAccessorTest.java
similarity index 95%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/MindMapAccessorTest.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/MindMapAccessorTest.java
index 2cadd5b..a6b8d71 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/api/MindMapAccessorTest.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/api/MindMapAccessorTest.java
@@ -1,4 +1,4 @@
-package io.fluentqa.mindmap.api;
+package io.fluent.mindmap.api;
import java.util.List;
import org.junit.jupiter.api.Test;
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/freemind/FreeMindConverterTest.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/freemind/FreeMindConverterTest.java
similarity index 74%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/freemind/FreeMindConverterTest.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/freemind/FreeMindConverterTest.java
index 9f5727e..b61be43 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/freemind/FreeMindConverterTest.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/freemind/FreeMindConverterTest.java
@@ -1,7 +1,8 @@
-package io.fluentqa.mindmap.freemind;
+package io.fluent.mindmap.freemind;
+
+import io.fluent.mindmap.api.MindMapPath;
+import io.fluent.mindmap.freemind.model.Node;
-import io.fluentqa.mindmap.api.MindMapPath;
-import io.fluentqa.mindmap.freemind.model.Node;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/xmind/XMindUtilTest.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/xmind/XMindUtilTest.java
similarity index 84%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/xmind/XMindUtilTest.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/xmind/XMindUtilTest.java
index cc7bec9..22ae77d 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/xmind/XMindUtilTest.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/xmind/XMindUtilTest.java
@@ -1,6 +1,6 @@
-package io.fluentqa.mindmap.xmind;
+package io.fluent.mindmap.xmind;
-import io.fluentqa.mindmap.xmind.model.XmindRawData;
+import io.fluent.mindmap.xmind.model.XmindRawData;
import org.junit.jupiter.api.Test;
class XMindUtilTest {
diff --git a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/xmind/XmindTransformerTest.java b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/xmind/XmindTransformerTest.java
similarity index 74%
rename from fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/xmind/XmindTransformerTest.java
rename to fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/xmind/XmindTransformerTest.java
index f307acc..f655e60 100644
--- a/fluent-wrappers/fluent-mindmap/src/test/java/io/fluentqa/mindmap/xmind/XmindTransformerTest.java
+++ b/fluent-wrappers/fluent-mindmap/src/test/java/io/fluent/mindmap/xmind/XmindTransformerTest.java
@@ -1,7 +1,8 @@
-package io.fluentqa.mindmap.xmind;
+package io.fluent.mindmap.xmind;
+
+import io.fluent.mindmap.api.MindMapPath;
+import io.fluent.mindmap.xmind.model.Attached;
-import io.fluentqa.mindmap.api.MindMapPath;
-import io.fluentqa.mindmap.xmind.model.Attached;
import java.util.List;
import org.junit.jupiter.api.Test;
diff --git a/fluent-wrappers/fluent-quickdao/sample.db b/fluent-wrappers/fluent-quickdao/sample.db
new file mode 100644
index 0000000..e69de29
diff --git a/fluent-wrappers/fluent-quickdao/src/main/java/io/fluent/quickdao/QuickDao.java b/fluent-wrappers/fluent-quickdao/src/main/java/io/fluent/quickdao/QuickDao.java
index c9dd265..41eb4fa 100644
--- a/fluent-wrappers/fluent-quickdao/src/main/java/io/fluent/quickdao/QuickDao.java
+++ b/fluent-wrappers/fluent-quickdao/src/main/java/io/fluent/quickdao/QuickDao.java
@@ -22,6 +22,7 @@ public class QuickDao {
Db db;
DataSource ds;
+
public static QuickDao createDao(T dsConfig) {
QuickDao dao = new QuickDao();
dao.dsConfig = dsConfig;
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/MarkdownAccessor.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/MarkdownAccessor.java
similarity index 58%
rename from fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/MarkdownAccessor.java
rename to fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/MarkdownAccessor.java
index 71c6e55..b452338 100644
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/MarkdownAccessor.java
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/MarkdownAccessor.java
@@ -1,3 +1,3 @@
-package io.fluentqa.md;
+package io.fluent.md;
public class MarkdownAccessor {}
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/package-info.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/package-info.java
new file mode 100644
index 0000000..93f2e6c
--- /dev/null
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/package-info.java
@@ -0,0 +1 @@
+package io.fluent.md;
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/FieldParseConfig.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/FieldParseConfig.java
similarity index 86%
rename from fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/FieldParseConfig.java
rename to fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/FieldParseConfig.java
index d4a5c1c..90949b9 100644
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/FieldParseConfig.java
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/FieldParseConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.md.parser;
+package io.fluent.md.parser;
import java.util.function.Function;
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/ParseConfig.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/ParseConfig.java
similarity index 93%
rename from fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/ParseConfig.java
rename to fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/ParseConfig.java
index aff5edb..4c329f5 100644
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/ParseConfig.java
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/ParseConfig.java
@@ -1,4 +1,4 @@
-package io.fluentqa.md.parser;
+package io.fluent.md.parser;
import cn.hutool.core.util.ReflectUtil;
import java.util.ArrayList;
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/AwesomeListParserConfig.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/AwesomeListParserConfig.java
similarity index 76%
rename from fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/AwesomeListParserConfig.java
rename to fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/AwesomeListParserConfig.java
index 856eaeb..47c8705 100644
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/AwesomeListParserConfig.java
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/AwesomeListParserConfig.java
@@ -1,6 +1,6 @@
-package io.fluentqa.md.parser.awesome;
+package io.fluent.md.parser.awesome;
-import io.fluentqa.md.parser.FieldParseConfig;
+import io.fluent.md.parser.FieldParseConfig;
import lombok.Data;
@Data
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/AwesomeModel.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/AwesomeModel.java
similarity index 79%
rename from fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/AwesomeModel.java
rename to fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/AwesomeModel.java
index e9f23c6..12dba73 100644
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/AwesomeModel.java
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/AwesomeModel.java
@@ -1,4 +1,4 @@
-package io.fluentqa.md.parser.awesome;
+package io.fluent.md.parser.awesome;
import lombok.Data;
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/MarkdownAwesomeListParser.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/MarkdownAwesomeListParser.java
similarity index 97%
rename from fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/MarkdownAwesomeListParser.java
rename to fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/MarkdownAwesomeListParser.java
index c45bbe3..17539c8 100644
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/parser/awesome/MarkdownAwesomeListParser.java
+++ b/fluent-wrappers/fluentqa-md/src/main/java/io/fluent/md/parser/awesome/MarkdownAwesomeListParser.java
@@ -1,4 +1,4 @@
-package io.fluentqa.md.parser.awesome;
+package io.fluent.md.parser.awesome;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
diff --git a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/package-info.java b/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/package-info.java
deleted file mode 100644
index cd7930c..0000000
--- a/fluent-wrappers/fluentqa-md/src/main/java/io/fluentqa/md/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package io.fluentqa.md;
diff --git a/fluent-wrappers/fluentqa-md/src/test/java/io/fluentqa/md/parsers/MarkdownAwesomeListParserTest.java b/fluent-wrappers/fluentqa-md/src/test/java/io/fluent/md/parsers/MarkdownAwesomeListParserTest.java
similarity index 95%
rename from fluent-wrappers/fluentqa-md/src/test/java/io/fluentqa/md/parsers/MarkdownAwesomeListParserTest.java
rename to fluent-wrappers/fluentqa-md/src/test/java/io/fluent/md/parsers/MarkdownAwesomeListParserTest.java
index 61fbe09..7b40749 100644
--- a/fluent-wrappers/fluentqa-md/src/test/java/io/fluentqa/md/parsers/MarkdownAwesomeListParserTest.java
+++ b/fluent-wrappers/fluentqa-md/src/test/java/io/fluent/md/parsers/MarkdownAwesomeListParserTest.java
@@ -1,4 +1,4 @@
-package io.fluentqa.md.parsers;
+package io.fluent.md.parsers;
import cn.hutool.json.JSONUtil;
import com.vladsch.flexmark.ast.BulletList;
@@ -8,8 +8,9 @@
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import io.fluent.builtin.JavaProjectFileUtils;
-import io.fluentqa.md.parser.awesome.AwesomeModel;
-import io.fluentqa.md.parser.awesome.MarkdownAwesomeListParser;
+import io.fluent.md.parser.awesome.AwesomeModel;
+import io.fluent.md.parser.awesome.MarkdownAwesomeListParser;
+
import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/Mock.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/Mock.java
deleted file mode 100644
index 5c988ba..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/Mock.java
+++ /dev/null
@@ -1,492 +0,0 @@
-package io.fluent.mocker;
-
-
-import com.forte.util.exception.MockException;
-import com.forte.util.factory.MockMapperFactory;
-import com.forte.util.factory.MockObjectFactory;
-import com.forte.util.factory.MockProxyHandlerFactory;
-import com.forte.util.factory.MockProxyHandlerFactoryImpl;
-import com.forte.util.loader.DefaultMockMethodLoader;
-import com.forte.util.loader.MethodLoader;
-import com.forte.util.mockbean.*;
-import com.forte.util.parser.ParameterParser;
-import com.forte.util.utils.ClassScanner;
-import com.forte.util.utils.MockUtil;
-import com.forte.util.utils.ProxyUtils;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- *
- * javaBean假数据生成工具
- *
- *
- * 使用静态方法:{@link #set(Class, Map)} 来添加一个类的假数据类型映射
- * 语法基本与Mock.js中的类似,字符串参数中可以使用@+方法名
的方式指定随机方法(随机方法详见{@link MockUtil},此类也可以直接使用)
- *
- *
- *
- * 使用的时候,请务必保证填充假数据的字段有他的getter方法
- * 使用多层级赋值的时候,请注意保证多层级中涉及的深层对象有无参构造方法
- *
- *
- *
- * 为类中的引用类型对象赋值的时候,有两种方式:
- *
- *
- *
- * map.set("user" , new HashMap)
- *
- * -> 即为字段再配置一个map映射集合
- *
- *
- *
- * map.set("user.name" , "@cname")
- *
- * -> 使用"."分割,即使用多层级对象赋值,此方式需要保证引用类型的对象有无参构造,且字段有getter方法
- *
- *
- *
- *
- * @author ForteScarlet
- * @version 0.5-beta
- */
-public class Mock {
-
- /* 静态代码块加载资源 */
- static {
- //创建线程安全的map集合,保存全部映射记录
- MOCK_OBJECT = new ConcurrentHashMap<>(4);
- MOCK_MAP = new ConcurrentHashMap<>(4);
-
- //创建map,这里的map理论上不需要线程同步
- Map mockUtilMethods;
-
- //加载这些方法,防止每次都使用反射去调用方法。
- //直接调用的话无法掌控参数,所以必须使用反射的形式进行调用
- Class mockUtilClass = MockUtil.class;
- //只获取公共方法
- Method[] methods = mockUtilClass.getMethods();
- /*
- 过滤Object中的方法、
- 将MockUtil中的全部方法名格式化 格式:方法名(参数类型class地址,参数类型class地址.....)、
- 转化为<方法名:方法>的map集合
- */
- mockUtilMethods =
- Arrays.stream(methods)
- //过滤掉Object中继承过来的方法
- .filter(m -> Arrays.stream(Object.class.getMethods()).noneMatch(om -> om.equals(m)))
- //格式化方法名,格式:方法名(参数类型class地址,参数类型class地址.....)
- .flatMap(m -> {
- Map methodMap = new HashMap<>();
- //格式化方法名,并作为key
- String key = m.getName() + "("
- + Arrays.stream(m.getParameterTypes())
- .map(Class::getName)
- .collect(Collectors.joining(",")) +
- ")";
- methodMap.put(key, m);
- return methodMap.entrySet().stream();
- }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
-
-
- //保存MockUtil中的全部方法
- MOCK_METHOD = mockUtilMethods;
- }
-
- /**
- * 保存全部记录的class与其对应的假对象{@link MockBean}
- */
- private static final Map MOCK_OBJECT;
-
- /**
- * Map类型假对象
- * TODO 后期考虑合并MOCK_OBJECT 和 MOCK_MAP两个字段
- */
- private static final Map MOCK_MAP;
-
-
- /**
- * MockUtil中的全部方法
- */
- private static final Map MOCK_METHOD;
-
-
- /**
- * 添加一个数据映射
- *
- * @param objClass 映射类型
- * @param map 映射对应值
- * @return 映射结果表
- */
- public static MockBean setResult(Class objClass, Map map, boolean reset) {
- //如果不是重新设置且此映射已经存在,并且objClass对象存在,将会抛出异常
- if (!reset && MOCK_OBJECT.get(objClass) != null) {
- throw new MockException("此映射已存在!");
- }
-
- MockBean parser;
-
- //使用参数解析器进行解析
- parser = ParameterParser.parser(objClass, map);
-
- //如果类型不是Map类型,添加
- MOCK_OBJECT.put(objClass, new MockNormalObject<>(parser));
-
- //提醒系统的垃圾回收
- System.gc();
-
- return parser;
- }
-
- /**
- * 添加一个map类型的映射
- *
- * @param resultName 映射名
- * @param map 映射值
- * @param reset 是否覆盖
- */
- public static MockMapBean setResult(String resultName, Map map, boolean reset) {
- //如果不是重新设置且此映射已经存在,并且objClass对象存在,将会抛出异常
- if (!reset && MOCK_MAP.get(resultName) != null) {
- throw new MockException("此映射已存在!this mock result has already exists.");
- }
-
- MockMapBean parser;
-
- //使用参数解析器进行解析
- parser = ParameterParser.parser(map);
- MOCK_MAP.put(resultName, MockObjectFactory.createMapObj(parser));
-
- //提醒系统的垃圾回收
- System.gc();
-
- return parser;
- }
-
-
- /**
- * 添加数据记录,如果要添加的映射已存在,则会抛出异常
- *
- * @param objClass 映射的class
- * @param map 映射的规则对象
- *
- *
- * key:对应的字段
- *
- * value:映射参数,可以是:
- *
- * 字符串
- * 若干随机方法指令(指令详见{@link MockUtil})
- * 整数(Integer)
- * 浮点数(Double)
- * 数组或集合类型
- * Map集合类型(可作为新的映射,也可直接作为参数)
- * 任意引用数据类型
- *
- *
- *
- *
- *
- * 如果映射的对象中有多层级对象,支持使用多层级字段映射,例如:
- *
- * map.put("friend.name" , "@cname");
- *
- *
- */
- public static void set(Class objClass, Map map) {
- //设置并保存映射,不可覆盖
- setResult(objClass, map, false);
- }
-
- /**
- * {@link #set(Class, Map)} and {@link #get(Class)}
- */
- public static MockObject setAndGet(Class objClass, Map map){
- set(objClass, map);
- return get(objClass);
- }
-
- /**
- * 通过注解来获取映射
- */
- public static void set(Class objClass) {
- //获取映射Map
- Map mapper = MockMapperFactory.getMapper(objClass);
- setResult(objClass, mapper, false);
- }
-
- /**
- * {@link #set(Class, Map)} and {@link #get(Class)}
- */
- public static MockObject setAndGet(Class objClass){
- set(objClass);
- return get(objClass);
- }
-
- /**
- * 通过注解来获取映射, 并提供额外的、难以用注解进行表达的映射参数
- */
- public static void setWithOther(Class objClass, Map other) {
- //获取映射Map
- Map mapper = MockMapperFactory.getMapper(objClass, other);
- setResult(objClass, mapper, false);
- }
-
-
- /**
- * 添加数据记录,如果要添加的映射已存在,则会抛出异常
- *
- * @param resultName
- * @param map
- */
- public static void set(String resultName, Map map) {
- //设置并保存映射,不可覆盖
- setResult(resultName, map, false);
- }
-
-
- /**
- * {@link #set(Class, Map)} and {@link #get(Class)}
- */
- public static MockObject setAndGet(String resultName, Map map){
- set(resultName, map);
- return get(resultName);
- }
-
-
- /**
- * 添加数据记录,如果要添加的映射已存在,则会覆盖
- *
- * @param objClass
- * @param map
- * @param
- */
- public static void reset(Class objClass, Map map) {
- //设置并保存映射
- setResult(objClass, map, true);
- }
-
- /**
- * 通过注解来获取映射
- */
- public static void reset(Class objClass) {
- //获取映射Map
- Map mapper = MockMapperFactory.getMapper(objClass);
- setResult(objClass, mapper, true);
- }
-
- /**
- * 通过注解来获取映射, 并提供额外的、难以用注解进行表达的映射参数
- */
- public static void resetWithOther(Class objClass, Map other) {
- //获取映射Map
- Map mapper = MockMapperFactory.getMapper(objClass, other);
- setResult(objClass, mapper, true);
- }
-
-
- /**
- * 添加数据记录,如果要添加的映射已存在,则会覆盖
- *
- * @param resultName
- * @param map
- * @param
- */
- public static void reset(String resultName, Map map) {
- //设置并保存映射
- setResult(resultName, map, true);
- }
-
-
- /**
- * 获取一个实例对象
- *
- * @param objClass
- * @param
- * @return
- */
- public static MockObject get(Class objClass) {
- return Optional.ofNullable(MOCK_OBJECT.get(objClass)).orElse(null);
- }
-
- /**
- * 获取一个实例对象
- *
- * @param resultName
- * @param
- * @return
- */
- public static MockObject get(String resultName) {
- return Optional.ofNullable(MOCK_MAP.get(resultName)).orElse(null);
- }
-
- /**
- * 扫描包路径,加载标记了{@link com.forte.util.mapper.MockBean}注解的类。
- *
- * @param classLoader nullable, 类加载器, null则默认为当前类加载器
- * @param withOther nullable, 假如扫描的类中存在某些类,你想要为它提供一些额外的参数,此函数用于获取对应class所需要添加的额外参数。可以为null
- * @param reset 加载注解映射的时候是否使用reset
- * @param packages emptyable, 要扫描的包路径列表, 为空则直接返回空set
- * @return 扫描并加载成功的类
- * @throws Exception 包扫描过程中可能会出现一些例如类找不到等各种异常。需要进行处理。
- */
- public static Set> scan(ClassLoader classLoader, Function, Map> withOther, boolean reset, String... packages) throws Exception {
- if (packages.length == 0) {
- return new HashSet<>();
- }
- // 包扫描器
- final ClassScanner scanner = classLoader == null ? new ClassScanner() : new ClassScanner(classLoader);
-
- // 扫描所有的包路径
- for (String p : packages) {
- scanner.find(p, c -> c.getAnnotation(com.forte.util.mapper.MockBean.class) != null);
- }
-
- // 扫描完了之后,load
- final Set> classes = scanner.get();
-
- classes.forEach(c -> {
- if (withOther != null) {
- if (reset) {
- resetWithOther(c, withOther.apply(c));
- } else {
- setWithOther(c, withOther.apply(c));
- }
- } else {
- if (reset) {
- reset(c);
- } else {
- set(c);
- }
- }
- });
-
- return classes;
- }
-
- /**
- * {@link #scan(ClassLoader, Function, boolean, String...)}的重载方法
- *
- * @see #scan(ClassLoader, Function, boolean, String...)
- */
- public static Set> scan(Function, Map> withOther, boolean reset, String... packages) throws Exception {
- return scan(null, withOther, reset, packages);
- }
-
- /**
- * {@link #scan(ClassLoader, Function, boolean, String...)}的重载方法
- *
- * @see #scan(ClassLoader, Function, boolean, String...)
- */
- public static Set> scan(boolean reset, String... packages) throws Exception {
- return scan(null, null, reset, packages);
- }
-
- /**
- * {@link #scan(ClassLoader, Function, boolean, String...)}的重载方法
- * reset默认为false
- *
- * @see #scan(ClassLoader, Function, boolean, String...)
- */
- public static Set> scan(String... packages) throws Exception {
- return scan(null, null, false, packages);
- }
-
- /**
- * 为一个接口提供一个代理对象。此接口中,所有的 抽象方法 都会被扫描,假如他的返回值存在与Mock中,则为其创建代理。
- * 此方法默认不会为使用者保存单例,每次代理都会代理一个新的对象,因此如果有需要,请保存一个单例对象而不是频繁代理。
- * @param type 要代理的接口类型。
- * @param factory 接口代理处理器的获取工厂。可自行实现。
- * @param 接口类型
- * @return 代理结果
- */
- public static T proxy(Class type, MockProxyHandlerFactory factory) {
- // 验证是否为接口类型
- if (!Modifier.isInterface(type.getModifiers())) {
- throw new IllegalArgumentException("type ["+ type +"] is not a interface type.");
- }
-
- // 获取代理处理器
- final InvocationHandler proxyHandler = factory.getHandler((returnType, name) -> {
- MockObject> mockObject = null;
- if (name != null) {
- mockObject = get(name);
- }
- if (mockObject == null) {
- mockObject = get(returnType);
- }
- return mockObject;
- });
-
- // 返回结果
- return ProxyUtils.proxy(type, proxyHandler);
- }
-
- /**
- * 为一个接口提供一个代理对象。此接口中,所有的 抽象方法 都会被扫描,假如他的返回值存在与Mock中,则为其创建代理。
- * 此方法默认不会为使用者保存单例,每次代理都会代理一个新的对象,因此如果有需要,请保存一个单例对象而不是频繁代理。
- * 使用默认的接口代理处理器工厂{@link MockProxyHandlerFactoryImpl}。
- * 默认处理工厂中,代理接口时,被代理的方法需要:
- * 不是default方法。default方法会根据其自己的逻辑执行。
- * 没有参数
- * 没有标注{@code @MockProxy(ignore=true) ignore=true的时候代表忽略}
- *
- * @see MockProxyHandlerFactoryImpl
- * @param type 要代理的接口类型。
- * @return 接口代理
- */
- public static > T proxy(C type) {
- return proxy(type, new MockProxyHandlerFactoryImpl());
- }
-
- /**
- * 获取方法加载器
- *
- * @return
- */
- public static MethodLoader mockMethodLoader() {
- return new DefaultMockMethodLoader(MOCK_METHOD);
- }
-
- /**
- * Deprecated
- *
- * @see #getMockMethods()
- */
- @Deprecated
- public static Map _getMockMethod() {
- return getMockMethods();
- }
-
- /**
- * 获取Mock方法集合
- *
- * @return 全部已被加载的映射方法
- */
- public static Map getMockMethods() {
- return new HashMap<>(MOCK_METHOD);
- }
-
-
- /**
- * 根据过滤条件寻找指定的string-method
- */
- public static Map.Entry getMockMethodByFilter(Predicate super Map.Entry> predicate){
- for (Map.Entry entry : MOCK_METHOD.entrySet()) {
- if(predicate.test(entry)){
- return entry;
- }
- }
- return null;
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/MockConfiguration.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/MockConfiguration.java
deleted file mode 100644
index 2cbfc09..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/MockConfiguration.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package io.fluent.mocker;
-import javax.script.ScriptEngine;
-
-/**
- *
- * 这是一个静态类,你可以随时随地修改他的配置。
- * 他的一些配置会在某些地方用到。
- *
- * @author ForteScarlet
- */
-public class MockConfiguration {
-
- /**
- * 是否启用JS脚本执行。
- *
版本1.8之后将脚本执行类{@link ScriptEngine}变更为了复用的单例形式,
- * 效率提升了约2倍多(测试生成1000条数据,优化前:14s左右,优化后:6s左右)
- *
6秒还是太慢了,因此现在修改为默认情况下不开启JS脚本执行,
- * 未开启配置的情况下,任何字符串类型的值都不再会尝试进行JS脚本执行。
- *
关闭脚本的效率比开启脚本的效率高15倍左右(测试生成1000条数据,开启JS:6左右,关闭JS:0.4秒左右)
- *
- *
- *
- */
- private static boolean enableJsScriptEngine = false;
-
- /**
- * 配置是否开启JS脚本执行
- */
- public static synchronized void setEnableJsScriptEngine(boolean enableJsScriptEngine){
- MockConfiguration.enableJsScriptEngine = enableJsScriptEngine;
- }
-
- /**
- * 获取是否开启JS脚本执行。
- * @return
- */
- public static boolean isEnableJsScriptEngine(){
- return enableJsScriptEngine;
- }
-
-
-
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/MockException.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/MockException.java
deleted file mode 100644
index fbc76d7..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/MockException.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.fluent.mocker.exception;
-
-
-public class MockException extends RuntimeException {
- public MockException() {
- }
- public MockException(String message) {
- super(message);
- }
-
- public MockException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public MockException(Throwable cause) {
- super(cause);
- }
-
- public MockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/MockParserException.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/MockParserException.java
deleted file mode 100644
index b4c98fa..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/MockParserException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.fluent.mocker.exception;
-
-
-public class MockParserException extends MockException{
-
- public MockParserException() {
- }
- public MockParserException(String message) {
- super(message);
- }
-
- public MockParserException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public MockParserException(Throwable cause) {
- super(cause);
- }
-
- public MockParserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/ParameterSizeException.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/ParameterSizeException.java
deleted file mode 100644
index f448c24..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/exception/ParameterSizeException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.fluent.mocker.exception;
-
-public class ParameterSizeException extends MockException {
- public ParameterSizeException() {
- super("参数数量与方法参数数量不符!");
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockBeanFactory.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockBeanFactory.java
deleted file mode 100644
index e8d6c91..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockBeanFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.fluent.mocker.factory;
-
-
-import io.fluent.mocker.mockbean.MockBean;
-import io.fluent.mocker.mockbean.MockField;
-import io.fluent.mocker.mockbean.MockMapBean;
-
-
-public class MockBeanFactory {
-
- /**
- * 创建一个MockBean
- * @param objectClass
- * @param fields
- * @param
- * @return
- */
- public static MockBean createMockBean(Class objectClass, MockField[] fields){
- return new MockBean<>(objectClass, fields);
- }
-
- /**
- * 创建一个MockMapBean
- * @param fields
- * @return
- */
- public static MockMapBean createMockMapBean(MockField[] fields){
- return new MockMapBean(fields);
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockMapperFactory.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockMapperFactory.java
deleted file mode 100644
index b15d82d..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockMapperFactory.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package io.fluent.mocker.factory;
-
-
-import org.apache.commons.beanutils.ConvertUtils;
-
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-/**
- * 生成映射Map的工厂
- *
- * @author ForteScarlet <[email]ForteScarlet@163.com>
- * @since JDK1.8
- **/
-public class MockMapperFactory {
-
- /**
- * 通过一个类的注解来生成映射,然后再整合额外的指定参数
- *
- * @param type 类型
- * @param other 额外参数,可以为null
- */
- public static Map getMapper(Class> type, Map other) {
- Map mapper = Arrays.stream(type.getDeclaredFields()).map(f -> {
- //由于目前只有两种注解,直接判断下就行了
- //优先使用MockValue的值
- Map.Entry, String> valueAndParam = getValue(f.getAnnotation(MockValue.class));
- if (valueAndParam == null) {
- valueAndParam = getValue(f.getAnnotation(MockArray.class));
- }
- // 无注解,返回null并由后续过滤
- if(valueAndParam == null){
- return null;
- }
- return new AbstractMap.SimpleEntry<>(f.getName() + valueAndParam.getValue(), valueAndParam.getKey().get());
- }).filter(Objects::nonNull).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
-
- if(other != null){
- mapper.putAll(other);
- }
- return mapper;
- }
-
- /**
- * 通过一个类的注解来生成映射
- *
- * @param type 类型
- */
- public static Map getMapper(Class> type) {
- return getMapper(type, null);
- }
-
- /**
- * 通过注解MockValue类型来获取value值
- * 如果为null或者值没有(保留空字符),则返回null
- * @return {@code Entry, fieldParam>} , 返回一个entry,key为value中的值的获取函数,value为map映射中字段的区间参数值。
- */
- public static Map.Entry, String> getValue(MockValue mockValueAnnotation) {
- if (mockValueAnnotation == null || mockValueAnnotation.value().length() <= 0) {
- return null;
- }
- final String mapValue = mockValueAnnotation.value();
- final Class> valueType = mockValueAnnotation.valueType();
-
- Supplier valueGetter = valueType.equals(String.class) ? () -> mapValue : () -> ConvertUtils.convert(mapValue, valueType);
-
- String param = mockValueAnnotation.param().trim();
- if(param.length() > 0 && !param.startsWith("|")){
- param = "|" + param;
- }
- return new AbstractMap.SimpleEntry<>(valueGetter, param);
- }
-
- /**
- * 通过注解MockValue类型来获取value值
- * @return {@code Entry, fieldParam>} , 返回一个entry,key为value中的值的获取函数,value为map映射中字段的区间参数值。
- */
- public static Map.Entry, String> getValue(MockArray mockArrayAnnotation) {
- if (mockArrayAnnotation == null) {
- return null;
- }
- try {
- ArrayMapper arrayMapper = mockArrayAnnotation.mapper().newInstance();
- final String[] mockArrayValue = mockArrayAnnotation.value();
- final Supplier valueGetter = () -> arrayMapper.map(mockArrayValue);
- String param = mockArrayAnnotation.param().trim();
- if(param.length() > 0 && !param.startsWith("|")){
- param = "|" + param;
- }
- return new AbstractMap.SimpleEntry<>(valueGetter, param);
- } catch (InstantiationException | IllegalAccessException e) {
- throw new MockException("无法实例化数组转化器 Cannot instantiate an array converter :" + mockArrayAnnotation.mapper());
- }
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockObjectFactory.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockObjectFactory.java
deleted file mode 100644
index cf4700d..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockObjectFactory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.fluent.mocker.factory;
-
-import com.forte.util.mockbean.*;
-
-/**
- * MockObject对象工厂
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date 2019/2/27 14:38
- */
-public class MockObjectFactory {
-
- /**
- * 创建一个普通mock对象
- * @param mockBean
- * @param
- * @return
- */
- public static MockObject createNormalObj(MockBean mockBean){
- return new MockNormalObject<>(mockBean);
- }
-
-
- /**
- * 创建一个map类型的mock对象
- * @param mockMapBean
- * @return
- */
- public static MockMapObject createMapObj(MockMapBean mockMapBean){
- return new MockMapObject(mockMapBean);
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockProxyHandlerFactory.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockProxyHandlerFactory.java
deleted file mode 100644
index 010df91..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockProxyHandlerFactory.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.fluent.mocker.factory;
-
-import com.forte.util.mockbean.MockObject;
-
-import java.lang.reflect.InvocationHandler;
-import java.util.function.BiFunction;
-
-/**
- * Mock接口代理对象工厂的接口定义
- * @author ForteScarlet
- */
-public interface MockProxyHandlerFactory {
-
- /**
- * 获取代理处理接口{@link InvocationHandler}实例
- * @param mockObjectFunction 传入一个类型和一个可能为null的name字符串,获取一个mockObject对象。如果存在name,则会尝试先用name获取
- * @return JDK动态代理所需要的代理处理器示例。
- * @see InvocationHandler
- */
- InvocationHandler getHandler(BiFunction, String, MockObject>> mockObjectFunction);
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockProxyHandlerFactoryImpl.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockProxyHandlerFactoryImpl.java
deleted file mode 100644
index d77a46c..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/MockProxyHandlerFactoryImpl.java
+++ /dev/null
@@ -1,257 +0,0 @@
-package io.fluent.mocker.factory;
-
-import com.forte.util.mapper.MockProxy;
-import com.forte.util.mapper.MockProxyType;
-import com.forte.util.mockbean.MockObject;
-import com.forte.util.utils.FieldUtils;
-
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiFunction;
-
-/**
- * {@link MockProxyHandlerFactory}的默认实现
- *
- * @author ForteScarlet
- */
-public class MockProxyHandlerFactoryImpl implements MockProxyHandlerFactory {
-
- /**
- * 获取接口代理处理器实例
- * 首先,只扫描所有的抽象方法,default方法不会代理,而是执行它自己。
- *
- * @param mockObjectFunction 传入一个类型,获取一个mockObject对象。如果是Map类型,则第二参数为map的名称,否则忽视第二参数。
- * @return 接口代理处理器实例
- */
- @Override
- public InvocationHandler getHandler(BiFunction, String, MockObject>> mockObjectFunction) {
- return new DefaultMockProxyHandler(mockObjectFunction);
- }
-
-
- /**
- * 默认的mock接口代理处理器实现
- */
- public static class DefaultMockProxyHandler implements InvocationHandler {
-
-
- /**
- * mockObject获取器
- */
- private BiFunction, String, MockObject>> mockObjectFunction;
-
- /**
- * 方法返回值缓存map。
- */
- private Map> methodReturnCacheMap;
-
- /**
- * 返回值永远为null的缓存值
- */
- private final SimpleBean nullValueCache = new SimpleBean<>((p, m, o) -> null);
-
- /**
- * 构造需要一个mockObject获取器
- */
- public DefaultMockProxyHandler(BiFunction, String, MockObject>> mockObjectFunction) {
- this.mockObjectFunction = mockObjectFunction;
- this.methodReturnCacheMap = new ConcurrentHashMap<>(2);
- }
-
- /**
- * 记录缓存
- */
- private void saveCache(Method m, InvocationHandler handler) {
- methodReturnCacheMap.put(m, new SimpleBean<>(handler));
- }
-
-
- /**
- * 记录缓存
- */
- private void saveNullCache(Method m) {
- methodReturnCacheMap.put(m, nullValueCache);
- }
-
-
- private InvocationHandler getCache(Method m) {
- final SimpleBean supplierAtomicReference = methodReturnCacheMap.get(m);
- return supplierAtomicReference == null ? null : supplierAtomicReference.get();
- }
-
- /**
- * 函数接口
- *
- * @param method 第一参数
- * @param args 第二参数
- * @return 返回值
- * @throws Throwable 任意异常
- */
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- // 先尝试获取缓存
- final InvocationHandler cache = getCache(method);
- if (cache != null) {
- return cache.invoke(proxy, method, args);
- }
-
- //如果是接口中的默认方法,使用特殊方法执行
- //代码源于网络: http://www.it1352.com/988865.html
- if (method.isDefault()) {
- Class> declaringClass = method.getDeclaringClass();
- Constructor constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
- constructor.setAccessible(true);
- InvocationHandler defaultInvocationHandler = (p, m, o) -> constructor.
- newInstance(declaringClass, MethodHandles.Lookup.PRIVATE).
- unreflectSpecial(method, declaringClass).
- bindTo(proxy).
- invokeWithArguments(args);
-
- // 记录缓存
- saveCache(method, defaultInvocationHandler);
- return defaultInvocationHandler.invoke(proxy, method, args);
- }
-
- // 尝试获取@MockProxy注解
- final MockProxy mockProxyAnnotation = method.getAnnotation(MockProxy.class);
- boolean ignore = mockProxyAnnotation != null && mockProxyAnnotation.ignore();
- // 返回值类型
- final Class> returnType = method.getReturnType();
-
- // 如果忽略此函数,则跳过
- if (ignore) {
- return getDefaultResultAndCache(returnType, method);
- }
-
- // 没有忽略,进行解析
- Class> genericType = mockProxyAnnotation == null ? Object.class : mockProxyAnnotation.genericType();
- String name = mockProxyAnnotation == null ? null : mockProxyAnnotation.name().trim().length() == 0 ? null : mockProxyAnnotation.name().trim();
- int[] array = mockProxyAnnotation == null ? new int[]{1, 1} : mockProxyAnnotation.size();
-
- // 准备参数
- MockProxyType proxyType = mockProxyAnnotation == null ? MockProxyType.UNKNOWN : mockProxyAnnotation.proxyType();
- // 如果是未知类型,根据返回值类型进行匹配。
- if(proxyType == MockProxyType.UNKNOWN){
- // 判断一下返回值的类型,如果是数组,转化为数组类型,如果是list,转化为list类型
- if(returnType.isArray()){
- final Class> arrayComponentType = returnType.getComponentType();
- genericType = genericType.equals(Object.class) ? arrayComponentType : genericType;
- proxyType = MockProxyType.ARRAY;
- }else if(FieldUtils.isChild(returnType, List.class)){
- proxyType = MockProxyType.LIST;
- }else{
- // 其他类型,认定为Object类型
- proxyType = MockProxyType.OBJECT;
- }
- }
-
-
- if (array.length == 0) {
- array = new int[]{1, 1};
- }
- if (array.length == 1) {
- array = new int[]{array[0], array[0]};
- }
- if (array.length > 2) {
- array = new int[]{array[0], array[1]};
- }
-
-
- // 要获取的mock类型
- Class> mockGetType = proxyType.selectTypeUse(returnType, genericType);
-
-
- final MockObject> mockObject = mockObjectFunction.apply(mockGetType, name);
-
- if (mockObject == null) {
- // 获取不到mockObject, 获取默认返回值
- return getDefaultResultAndCache(returnType, method);
- }
-
- // mockObject不为null,构建返回值
-
- final int[] finalArr = array;
-
- final MockProxyType finalProxyType = proxyType;
-
- // 构建缓存函数
- InvocationHandler proxyHandler = (p, m, o) -> finalProxyType.buildReturnType(num -> {
- if (num == 1) {
- return new Object[]{mockObject.getOne()};
- } else if (num == 0) {
- return new Object[0];
- } else if (num < 0) {
- throw new IllegalArgumentException("size cannot be zero.");
- } else {
- return mockObject.getStream(num).toArray(Object[]::new);
- }
- }, mockGetType, finalArr[0], finalArr[1]);
-
- saveCache(method, proxyHandler);
- return proxyHandler.invoke(proxy, method, args);
- }
-
- /**
- * 获取默认返回值并缓存
- *
- * @param returnType 返回值类型
- * @param method 方法
- */
- private Object getDefaultResultAndCache(Class> returnType, Method method) {
- final Object defaultResult = getDefaultResult(returnType);
- // 记录缓存
- if (defaultResult == null) {
- saveNullCache(method);
- } else {
- InvocationHandler ignoreHandler = (p, m, o) -> defaultResult;
- saveCache(method, ignoreHandler);
- }
- return defaultResult;
- }
-
-
- /**
- * 获取默认返回值
- *
- * @param returnType 返回值类型
- */
- private Object getDefaultResult(Class> returnType) {
- // char
- if (returnType.equals(char.class)) {
- return ' ';
- }
- // boolean
- if (returnType.equals(boolean.class)) {
- return false;
- }
-
- // 浮点型
- Class>[] basicFloatTypes = new Class[]{double.class, float.class};
- for (Class> basicFloatType : basicFloatTypes) {
- if (returnType.equals(basicFloatType)) {
- return 0.0;
- }
- }
-
- // 整型
- Class>[] basicNumberTypes = new Class[]{byte.class, short.class, int.class, long.class};
- for (Class> basicNumberType : basicNumberTypes) {
- if (returnType.equals(basicNumberType)) {
- return 0;
- }
- }
-
- // 其他的返回null
- return null;
- }
-
-
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/SimpleBean.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/SimpleBean.java
deleted file mode 100644
index fa0113c..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/factory/SimpleBean.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.fluent.mocker.factory;
-
-import java.util.function.Supplier;
-
-/**
- * 就是一个类的一层封装类
- * @author ForteScarlet
- */
-public class SimpleBean implements Supplier {
-
- private T bean = null;
-
- public SimpleBean(){ }
- public SimpleBean(T bean){
- this.bean = bean;
- }
-
- public void set(T bean){
- this.bean = bean;
- }
-
- /**
- * Gets a result.
- * @return a result
- */
- @Override
- public T get() {
- return bean;
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ArrayFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ArrayFieldValueGetter.java
deleted file mode 100644
index e099b72..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ArrayFieldValueGetter.java
+++ /dev/null
@@ -1,238 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-import com.forte.util.exception.MockException;
-import com.forte.util.invoker.Invoker;
-import com.forte.util.utils.MethodUtil;
-import com.forte.util.utils.RandomUtil;
-
-import javax.script.ScriptException;
-
-/**
- * 数组类型的字段值获取器,与{@link ListFieldValueGetter}十分相似,基本可是说是只有参数类似不同了
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class ArrayFieldValueGetter implements FieldValueGetter {
-
- /**
- * 方法执行者们
- * 期望中 只有一个执行者
- * 不排除多个执行者的情况,
- * 但是如果是多个执行者,List集合很大可能是String、Integer之类的基础数据类型
- */
- private final Invoker[] invokers;
-
- /**
- * 区间参数,重复最终输出,参数期望中长度为2,0索引为最小值,1为最大值
- * 默认值为[1,1],即为不重复
- */
- private final Integer[] integerInterval;
-
- /**
- * 多余字符
- * 集合字段的指令类参数中可能出现多余字符,当有多于字符的时候,list集合的类型有很大的概率是Sting、Integer之类的基础数据类型
- */
- private final String[] moreStrs;
-
- /**
- * 获取一个数组
- *
- * @return
- */
- @Override
- public Object[] value() {
- //获取执行次数
- Integer min = integerInterval[0];
- Integer max = integerInterval[1];
- int num = (max == null ? min : RandomUtil.getNumberWithRight(min, max));
- //创建一个Object类型的List集合,用于保存数据
- Object[] list = new Object[num];
- //判断执行者的数量
- if (invokers.length > 1) {
-
- //当执行者数量大于1,执行方法
- getValueWhenInvokersMoreThan1(num, list);
-
- } else if (invokers.length <= 0) {
- /*
- * 没有执行者的情况,创建并返回一个空的字符串集合
- * 一般情况下不会出现空执行者的情况,就算是没有可执行方法也会有空值执行者
- */
- return new Object[0];
- } else {
-
- //当执行者的数量不大于1的时候,执行方法
- getValueWhenInvokerIs1(num, list);
- }
- //返回结果
- return list;
- }
-
- /**
- * 当执行者的数量超过1的时候
- *
- * @param num
- * @param list
- */
- private void getValueWhenInvokersMoreThan1(int num, Object[] list) {
- //执行者数量大于1的情况下,只能将全部执行结果的toString拼接,并尝试使用eval进行执行
- //如果eval可以执行,则保存eval中得到的结果,如果无法执行则返回拼接字符串
- StringBuilder sb = new StringBuilder();
- //开始遍历并执行
- try {
- for (int i = 0; i < num; i++) {
- //执行全部执行者
- for (int j = 0; j < invokers.length; j++) {
- //如果有多余字符,先拼接多余字符
- if (moreStrs != null) {
- sb.append(moreStrs[j]);
- }
- //拼接执行结果
- sb.append(invokers[j].invoke());
- }
- //如果有多余字符且多余字符的数量比执行者多1
- //只要多余字符比执行者数量大,则说明多余字符的数量为执行者的数量+1
- if (moreStrs != null && moreStrs.length > invokers.length) {
- //拼接多余字符的最后值
- sb.append(moreStrs[moreStrs.length - 1]);
- }
- String invokeStr = sb.toString();
- try {
- //尝试使用eval进行执行
- Object eval = MethodUtil.eval(invokeStr);
- //如果能执行成功,保存这个执行结果到集合
- list[i] = (eval);
- } catch (ScriptException e) {
- //如果执行失败,保存执行前的字符串
- list[i] = (invokeStr);
- }
- }
- } catch (Exception e) {
- throw new MockException(e);
- }
- }
-
-
- /**
- * 当执行者数量不大于1的时候
- *
- * @param num
- * @param list
- */
- private void getValueWhenInvokerIs1(int num, Object[] list) {
-
- //执行者数量不大于1,即只有一个
- Invoker invoker = invokers[0];
- //尽管只有一个方法执行者,但是仍然可能存在多余字符
- //所以分两种情况
- //在有多余字符的情况下,处理方式类似于上面的多执行者
- if (moreStrs != null) {
- //如果存在多余字符
- //准备拼接结果
- StringBuilder sb = new StringBuilder();
- //遍历num次数
- try {
- for (int i = 0; i < num; i++) {
- //先拼接多余字符,再拼接方法执行结果
- sb.append(moreStrs[i]);
- //方法的执行结果
- sb.append(invoker.invoke());
- //如果多余字符有结尾,拼接
- //由于只有一个执行者,所以如果多余字符数量大于1就说明有尾部多余
- if (moreStrs.length > 1) {
- //这里的元素索引不出意外的话,必定是2
- sb.append(moreStrs[moreStrs.length - 1]);
- }
- String invokeData = sb.toString();
- //尝试对结果进行eval
- //如果执行成功,保存执行结果
- list[i] = (MethodUtil.evalCache(invokeData));
- }
- } catch (Exception e) {
- throw new MockException(e);
- }
-
- } else {
- //没有多余字符
- //只有一个方法执行者、且没有多余字符的情况是最稳定的情况。
- //指令参数类型情况下,这种类型只有及低的可能会出现类型异常(只要你的list类型没有填写错误)
- //遍历num次数,执行执行者并将结果保存至list集合
- try {
- for (int i = 0; i < num; i++) {
- //执行结果
- list[i] = invoker.invoke();
- }
- } catch (Exception e) {
- throw new MockException(e);
- }
- }
- }
-
-
- /**
- * 构造方法
- *
- * @param invokers 方法执行者
- * @param integerInterval 区间参数
- * @param moreStrs 多余字符
- */
- public ArrayFieldValueGetter(Invoker[] invokers, Integer[] integerInterval, String[] moreStrs) {
- this.invokers = invokers;
- //如果多余字符长度为0,则赋值为null
- this.moreStrs = moreStrs.length == 0 ? null : moreStrs;
- //如果为true,则使用默认的数组
- boolean isNull = integerInterval == null || integerInterval.length > 2 || integerInterval[0] == null || integerInterval[1] == null;
- if (isNull) {
- this.integerInterval = new Integer[]{1, 1};
- } else {
- this.integerInterval = integerInterval;
- }
- }
-
- /**
- * 构造方法,区间参数默认为[1,1]
- *
- * @param invokers 方法执行者
- * @param moreStrs 多余字符
- */
- public ArrayFieldValueGetter(Invoker[] invokers, String[] moreStrs) {
- this.invokers = invokers;
- this.integerInterval = new Integer[]{1, 1};
- //如果多余字符长度为0,则赋值为null
- this.moreStrs = moreStrs.length == 0 ? null : moreStrs;
- }
-
-
- /**
- * 构造方法,没有多余字符
- *
- * @param invokers 方法执行者
- * @param integerInterval 区间参数
- */
- public ArrayFieldValueGetter(Invoker[] invokers, Integer[] integerInterval) {
- this.invokers = invokers;
- //判断:数组为null || 长度大于2 || 左参数为null || 左右参数都为null
- //如果为true,则使用默认的数组
- boolean isNull = integerInterval == null || integerInterval.length > 2 || integerInterval[0] == null || integerInterval[1] == null;
- if (isNull) {
- this.integerInterval = new Integer[]{1, 1};
- } else {
- this.integerInterval = integerInterval;
- }
- //多余字符赋值为null
- this.moreStrs = null;
- }
-
- /**
- * 构造方法,没有多余字符,区间参数默认为[1,1]
- *
- * @param invokers 方法执行者
- */
- public ArrayFieldValueGetter(Invoker[] invokers) {
- this.invokers = invokers;
- this.integerInterval = new Integer[]{1, 1};
- //多余字符赋值为null
- this.moreStrs = null;
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/DoubleFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/DoubleFieldValueGetter.java
deleted file mode 100644
index 9407eda..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/DoubleFieldValueGetter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-import com.forte.util.exception.MockException;
-import com.forte.util.invoker.Invoker;
-
-
-/**
- * Double类型字段值获取器
- * 既然使用了此字段值获取器,则说明已经确定了字段的类型,则必定不会出现多个执行者。
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class DoubleFieldValueGetter implements FieldValueGetter {
-
- /**
- * 方法执行者,用于获取double值
- * 方法执行者必定为1个
- */
- private Invoker invoker;
-
- @Override
- public Double value() {
- //直接返回执行结果
- try {
- return (Double) invoker.invoke();
- } catch (Exception e) {
- throw new MockException(e);
- }
- }
-
-
- /**
- * 构造方法,只需要一个方法执行者
- */
- public DoubleFieldValueGetter(Invoker invoker) {
- this.invoker = invoker;
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/EnumFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/EnumFieldValueGetter.java
deleted file mode 100644
index d64c824..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/EnumFieldValueGetter.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-/**
- *
- * 枚举类型的字段值获取器
- *
- * @deprecated 尚未实现完成
- *
- * @author ForteScarlet
- * @date 2020/8/1
- */
-@Deprecated
-public class EnumFieldValueGetter> implements FieldValueGetter> {
-
- @Override
- public Enum value() {
- return null;
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/FieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/FieldValueGetter.java
deleted file mode 100644
index 5fc533a..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/FieldValueGetter.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-/**
- * 字段值获取器
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-@FunctionalInterface
-public interface FieldValueGetter {
-
- /**
- * 获取这个字段的参数
- */
- T value();
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/IntegerFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/IntegerFieldValueGetter.java
deleted file mode 100644
index 1744926..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/IntegerFieldValueGetter.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-import com.forte.util.exception.MockException;
-import com.forte.util.invoker.Invoker;
-
-
-/**
- * 整数类型字段值获取器
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class IntegerFieldValueGetter implements FieldValueGetter {
-
- /**
- * 方法执行者用于获取整数类型的字段值
- * 执行者必然只有一个
- */
- private Invoker invoker;
-
-
- /**
- * 获取一个整数类型的字段值
- * @return
- */
- @Override
- public Integer value() {
- try {
- return (Integer) invoker.invoke();
- } catch (Exception e) {
- throw new MockException(e);
- }
- }
-
-
- /**
- * 构造方法,只需要一个方法执行者
- */
- public IntegerFieldValueGetter(Invoker invoker) {
- this.invoker = invoker;
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ListFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ListFieldValueGetter.java
deleted file mode 100644
index 33ffa22..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ListFieldValueGetter.java
+++ /dev/null
@@ -1,324 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-import com.forte.util.exception.MockException;
-import com.forte.util.invoker.Invoker;
-import com.forte.util.utils.MethodUtil;
-import com.forte.util.utils.RandomUtil;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.function.Supplier;
-
-/**
- * List集合的字段值获取器
- * 有较大的可能出现一些类型异常,请注意一定按照规范填写
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class ListFieldValueGetter implements FieldValueGetter {
-
-
- /**
- * 方法执行者们
- * 期望中 只有一个执行者
- * 不排除多个执行者的情况,
- * 但是如果是多个执行者,List集合很大可能是String、Integer之类的基础数据类型
- */
- private final Invoker[] invokers;
-
- /**
- * 区间参数,重复最终输出,参数期望中长度为2,0索引为最小值,1为最大值
- * 默认值为[1,1],即为不重复
- *
- * @since 1.7.0 当前版本替换为获取函数
- */
- private final Supplier integerIntervalSupplier;
-
- /**
- * 多余字符
- * 集合字段的指令类参数中可能出现多余字符,当有多于字符的时候,list集合的类型有很大的概率是Sting、Integer之类的基础数据类型
- */
- private final String[] moreStrs;
-
-
- /**
- * 获取字段值
- */
- @Override
- public List value() {
- Integer[] integerInterval = integerIntervalSupplier.get();
- //创建一个Object类型的List集合,用于保存数据
- List list = new ArrayList();
- //获取执行次数
- Integer min = integerInterval[0];
- Integer max = integerInterval[1];
- int num = (max == null ? min : RandomUtil.getNumberWithRight(min, max));
- //判断执行者的数量
- if (invokers.length > 1) {
-
- //当执行者数量大于1,执行方法
- getValueWhenInvokersMoreThan1(num, list);
-
- } else if (invokers.length <= 0) {
- /*
- * 没有执行者的情况,创建并返回一个空的字符串集合
- * 一般情况下不会出现空执行者的情况,就算是没有可执行方法也会有空值执行者
- */
-// return new ArrayList();
- return list;
- } else {
-
- //当执行者的数量不大于1的时候,执行方法
- getValueWhenInvokerIs1(num, list);
- }
- //返回结果
- return list;
- }
-
- /**
- * 当执行者的数量超过1的时候
- *
- * @param num
- * @param list
- */
- private void getValueWhenInvokersMoreThan1(int num, List list) {
- //执行者数量大于1的情况下,只能将全部执行结果的toString拼接,并尝试使用eval进行执行
- //如果eval可以执行,则保存eval中得到的结果,如果无法执行则返回拼接字符串
- StringBuilder sb = new StringBuilder();
- //开始遍历并执行
- try {
- for (int i = 0; i < num; i++) {
- //执行全部执行者
- for (int j = 0; j < invokers.length; j++) {
- //如果有多余字符,先拼接多余字符
- if (moreStrs != null) {
- sb.append(moreStrs[j]);
- }
- //拼接执行结果
- sb.append(invokers[j].invoke());
- }
-
- //如果有多余字符且多余字符的数量比执行者多1
- //只要多余字符比执行者数量大,则说明多余字符的数量为执行者的数量+1
- if (moreStrs != null && moreStrs.length > invokers.length) {
- //拼接多余字符的最后值
- sb.append(moreStrs[moreStrs.length - 1]);
- }
- String invokeStr = sb.toString();
- //尝试使用eval进行执行
- Object eval = MethodUtil.evalCache(invokeStr);
- //如果能执行成功,保存这个执行结果到集合
- list.add(eval);
- }
- } catch (Exception e) {
- throw new MockException(e);
- }
- }
-
-
- /**
- * 当执行者数量不大于1的时候
- *
- * @param num
- * @param list
- */
- private void getValueWhenInvokerIs1(int num, List list) {
- //执行者数量不大于1,即只有一个
- Invoker invoker = invokers[0];
- //尽管只有一个方法执行者,但是仍然可能存在多余字符
- //所以分两种情况
- //在有多余字符的情况下,处理方式类似于上面的多执行者
- if (moreStrs != null) {
- //如果存在多余字符
- //准备拼接结果
- StringBuilder sb = new StringBuilder();
- //遍历num次数
- try {
- for (int i = 0; i < num; i++) {
- //先拼接多余字符,再拼接方法执行结果
- sb.append(moreStrs[i]);
- //方法的执行结果
- sb.append(invoker.invoke());
- //如果多余字符有结尾,拼接
- //由于只有一个执行者,所以如果多余字符数量大于1就说明有尾部多余
- if (moreStrs.length > 1) {
- //这里的元素索引不出意外的话,必定是2
- sb.append(moreStrs[moreStrs.length - 1]);
- }
- String invokeData = sb.toString();
- //尝试对结果进行eval
- //如果执行成功,保存执行结果
- Object eval = MethodUtil.evalCache(invokeData);
- list.add(eval);
- }
- } catch (Exception e) {
- throw new MockException(e);
- }
- } else {
- //没有多余字符
- //只有一个方法执行者、且没有多余字符的情况是最稳定的情况。
- //指令参数类型情况下,这种类型只有及低的可能会出现类型异常(只要你的list类型没有填写错误)
- //遍历num次数,执行执行者并将结果保存至list集合
- try {
- for (int i = 0; i < num; i++) {
- //执行结果
- list.add(invoker.invoke());
- }
- } catch (Exception e) {
- throw new MockException(e);
- //如果执行出现错误,保存一个空值 null
-// list.add(null);
- }
- }
- }
-
-
- /**
- * 获取一个固定值的区间获取函数
- *
- * @param a 固定区间 a
- * @param b 固定区间 b
- */
- static Supplier normalIntegerIntervalSupplier(int a, int b) {
- Integer[] intervalsNew = new Integer[]{a, b};
- return () -> intervalsNew;
- }
-
- /**
- * 获取一个固定值的区间获取函数
- *
- * @param intervals 固定区间
- */
- static Supplier normalIntegerIntervalSupplier(Integer[] intervals) {
- Integer[] intervalsNew = Arrays.copyOf(intervals, intervals.length);
- return () -> intervalsNew;
- }
-
- /**
- * 根据两个区间来随机获取其中一个区间的函数
- *
- * @param intervals1 第一个区间
- * @param intervals2 第二个区间
- * @return 获取函数
- */
- static Supplier normalIntegerIntervalSupplier(Integer[] intervals1, Integer[] intervals2) {
- Integer[] intervals1New = Arrays.copyOf(intervals1, intervals1.length);
- Integer[] intervals2New = Arrays.copyOf(intervals2, intervals2.length);
- return () -> ThreadLocalRandom.current().nextBoolean() ? intervals1New : intervals2New;
- }
-
-
- /**
- * 构造方法
- *
- * @param invokers 方法执行者
- * @param integerInterval 区间参数
- * @param moreStrs 多余字符
- */
- public ListFieldValueGetter(Invoker[] invokers, Integer[] integerInterval, String[] moreStrs) {
- this.invokers = invokers;
- //如果多余字符长度为0,则赋值为null
- this.moreStrs = moreStrs.length == 0 ? null : moreStrs;
- //如果为true,则使用默认的数组
- boolean isNull = integerInterval == null || integerInterval.length > 2 || integerInterval[0] == null || integerInterval[1] == null;
- if (isNull) {
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(1, 1);
- } else {
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(integerInterval);
- }
- }
-
- /**
- * 构造方法
- *
- * @param invokers 方法执行者
- * @param integerInterval1 区间参数
- * @param integerInterval2 区间参数
- * @param moreStrs 多余字符
- */
- public ListFieldValueGetter(Invoker[] invokers, Integer[] integerInterval1, Integer[] integerInterval2, String[] moreStrs) {
- this.invokers = invokers;
- //如果多余字符长度为0,则赋值为null
- this.moreStrs = moreStrs.length == 0 ? null : moreStrs;
- //如果为true,则使用默认的数组
- boolean isNull1 = integerInterval1 == null || integerInterval1.length > 2 || integerInterval1[0] == null || integerInterval1[1] == null;
- boolean isNull2 = integerInterval2 == null || integerInterval2.length > 2 || integerInterval2[0] == null || integerInterval2[1] == null;
-
- Integer[] integerInterval1New = isNull1 ? new Integer[]{1, 1} : integerInterval1;
- Integer[] integerInterval2New = isNull2 ? integerInterval1New : integerInterval2;
-
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(integerInterval1New, integerInterval2New);
- }
-
- /**
- * 构造方法,区间参数默认为[1,1]
- *
- * @param invokers 方法执行者
- * @param moreStrs 多余字符
- */
- public ListFieldValueGetter(Invoker[] invokers, String[] moreStrs) {
- this.invokers = invokers;
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(1, 1);
- //如果多余字符长度为0,则赋值为null
- this.moreStrs = moreStrs.length == 0 ? null : moreStrs;
- }
-
- /**
- * 构造方法,没有多余字符
- *
- * @param invokers 方法执行者
- * @param integerInterval 区间参数
- */
- public ListFieldValueGetter(Invoker[] invokers, Integer[] integerInterval) {
- this.invokers = invokers;
- //判断:数组为null || 长度大于2 || 左参数为null || 左右参数都为null
- //如果为true,则使用默认的数组
- boolean isNull = integerInterval == null || integerInterval.length > 2 || integerInterval[0] == null || integerInterval[1] == null;
- if (isNull) {
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(1, 1);
- } else {
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(integerInterval);
- }
- //多余字符赋值为null
- this.moreStrs = null;
- }
-
- /**
- * 构造方法,没有多余字符
- *
- * @param invokers 方法执行者
- * @param integerInterval1 区间参数1
- * @param integerInterval2 区间参数2
- */
- public ListFieldValueGetter(Invoker[] invokers, Integer[] integerInterval1, Integer[] integerInterval2) {
- this.invokers = invokers;
- //判断:数组为null || 长度大于2 || 左参数为null || 左右参数都为null
- //如果为true,则使用默认的数组
- boolean isNull1 = integerInterval1 == null || integerInterval1.length > 2 || integerInterval1[0] == null || integerInterval1[1] == null;
- boolean isNull2 = integerInterval2 == null || integerInterval2.length > 2 || integerInterval2[0] == null || integerInterval2[1] == null;
-
- Integer[] integerInterval1New = isNull1 ? new Integer[]{1, 1} : integerInterval1;
- Integer[] integerInterval2New = isNull2 ? integerInterval1New : integerInterval2;
-
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(integerInterval1New, integerInterval2New);
-
- //多余字符赋值为null
- this.moreStrs = null;
- }
-
- /**
- * 构造方法,没有多余字符,区间参数默认为[1,1]
- *
- * @param invokers 方法执行者
- */
- public ListFieldValueGetter(Invoker[] invokers) {
- this.invokers = invokers;
- this.integerIntervalSupplier = normalIntegerIntervalSupplier(1, 1);
- //多余字符赋值为null
- this.moreStrs = null;
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ObjectFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ObjectFieldValueGetter.java
deleted file mode 100644
index 90745ef..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/ObjectFieldValueGetter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-import com.forte.util.exception.MockException;
-import com.forte.util.invoker.Invoker;
-import com.forte.util.utils.MethodUtil;
-
-import javax.script.ScriptException;
-
-/**
- * 字段类型为任意未知类型的时候
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class ObjectFieldValueGetter implements FieldValueGetter {
-
- /**
- * 方法执行者,期望值是只有一个,但是不能保证,假如有多个参数的话,尝试使用加法运算进行相加
- */
- private final Invoker[] invokers;
-
- /**
- * 获取值
- *
- * @return
- */
- @Override
- public Object value() {
- try {
- //如果只有一个执行者
- if (invokers.length > 1) {
- //不止一个,拼接结果为类js代码并执行eval()
- //用于执行eval的拼接字符串
- StringBuilder evalString = new StringBuilder();
- //用于防止执行出现错误的直接返回用的字符串
- StringBuilder returnString = new StringBuilder();
- //遍历执行并拼接
- for (int i = 0; i < invokers.length; i++) {
- if (i != 0) {
- evalString.append("+");
- }
- //执行结果
- Object invoke = invokers[i].invoke();
- evalString.append(invoke);
- returnString.append(invoke);
- }
- //遍历结束,执行加法运算并返回结果
- String forEval = evalString.toString();
- try {
- return MethodUtil.eval(forEval);
- } catch (ScriptException e) {
- //如果出现异常,则直接返回结果的拼接字符串
- return returnString.toString();
- }
- }else {
- //直接返回执行结果
- return invokers[0].invoke();
- }
- } catch (Exception e) {
- //出现异常,抛出
- throw new MockException(e);
- }
- }
-
-
- /**
- * 构造方法
- *
- * @param invokers 方法执行者
- */
- public ObjectFieldValueGetter(Invoker[] invokers) {
- this.invokers = invokers;
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/StringFieldValueGetter.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/StringFieldValueGetter.java
deleted file mode 100644
index 9e2e181..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/fieldvaluegetter/StringFieldValueGetter.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package io.fluent.mocker.fieldvaluegetter;
-
-
-import com.forte.util.exception.MockException;
-import com.forte.util.invoker.Invoker;
-import com.forte.util.utils.MethodUtil;
-import com.forte.util.utils.RandomUtil;
-
-import java.util.Collections;
-import java.util.function.Supplier;
-
-/**
- * 字符串类型字段值的获取者
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class StringFieldValueGetter implements FieldValueGetter {
-
- /**
- * 方法执行者,顺序与解析出来的方法和多余字符之间的顺序一致
- */
- private final Invoker[] invokers;
-
- /**
- * 多余字符,如果不为null,则长度必然是 方法执行者invokers 的数量的+1或者相同
- */
- private final String[] moreStr;
-
- /**
- * 区间参数,重复最终输出,参数期望中长度为2,0索引为最小值,1为最大值
- * 默认值为[1,1],即为不重复
- */
- private final Integer[] integerInterval;
-
-
- /**
- * 获取重复次数的获取函数。
- */
- private final Supplier timeSupplier;
-
-
- /**
- * 获取字段值
- *
- * @return
- */
- @Override
- public String value() {
- StringBuilder sb = new StringBuilder(32);
- //同时遍历方法与多余字符,使用methods遍历
- int i = 0;
- int invokerLength = invokers.length;
- try {
- for (; i < invokerLength; i++) {
- //如果有多余字符,先存多余字符,后存执行结果
- if (moreStr != null) {
- sb.append(moreStr[i]);
- }
-
- sb.append(invokers[i].invoke());
- }
- } catch (Exception e) {
- throw new MockException(e);
- }
- //如果多余字符不为空
- //判断多余字符的数量:
- // 如果数量相等,说明在最后的方法后面没有多余参数,
- // 如果数量多1,则说明在最后的方法后面还有多余字符
- //如果尾部有多余字符,添加
- if (moreStr != null && moreStr.length > invokerLength) {
- sb.append(moreStr[i]);
- }
-
- //重复输出,次数为integerInterval的参数
- //如果没有右参数,重复次数则为左参数
-// int times;
- int times = timeSupplier.get();
-// if(integerInterval[1] == null){
-// times = integerInterval[0];
-// }else{
-// int min = integerInterval[0];
-// int max = integerInterval[1];
-// times = RandomUtil.getNumberWithRight(min , max);
-// }
-
- //有些少数情况,end中拼接后的字符串是可以作为简单JS代码执行的,在此处重复字符串之前,尝试使用eval进行执行
- String end = String.valueOf(MethodUtil.evalCache(sb.toString()));
-
-
- //重复次数并返回
- if (times <= 1) {
- return end;
- } else {
- return String.join("", Collections.nCopies(times, end));
- }
- }
-
-
- /**
- * 构造
- *
- * @param invokers
- * @param moreStr
- */
- public StringFieldValueGetter(Invoker[] invokers, String[] moreStr, Integer[] integerInterval) {
- this.invokers = invokers;
- this.moreStr = moreStr;
- //判断:数组为null || 长度大于2 || 左参数为null || 左右参数都为null
- //如果为true,则使用默认的数组
- boolean isNull = integerInterval == null || integerInterval.length > 2 || integerInterval[0] == null || integerInterval[1] == null;
- if (isNull) {
- this.integerInterval = new Integer[]{1, 1};
- this.timeSupplier = () -> 1;
- } else {
- this.integerInterval = integerInterval;
- int min = integerInterval[0];
- int max = integerInterval[1];
- this.timeSupplier = () -> RandomUtil.getNumberWithRight(min, max);
- }
- }
-
- /**
- * 构造,区间参数默认为[1-1]
- *
- * @param invokers
- * @param moreStr
- */
- public StringFieldValueGetter(Invoker[] invokers, String[] moreStr) {
- this.invokers = invokers;
- this.moreStr = moreStr;
- //区间为默认值
- this.integerInterval = new Integer[]{1, 1};
- this.timeSupplier = () -> 1;
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/ExFunction.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/ExFunction.java
deleted file mode 100644
index a271ece..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/ExFunction.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.fluent.mocker.function;
-
-/**
- * 三个参数的function
- * @author ForteScarlet
- */
-@FunctionalInterface
-public interface ExFunction {
-
- /**
- * 接收三个参数,返回一个结果
- */
- R apply(T t, U1 u1, U2 u2);
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/ExProxyHandler.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/ExProxyHandler.java
deleted file mode 100644
index 9acf21c..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/ExProxyHandler.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package io.fluent.mocker.function;
-
-/**
- * 带着异常处理的BiFunction,用于构建动态代理的参数
- */
-@FunctionalInterface
-public interface ExProxyHandler {
- /**
- * 函数接口
- *
- * @param t 第一参数
- * @param u 第二参数
- * @return 返回值
- * @throws Throwable 任意异常
- */
- R apply(T t, U u) throws Throwable;
-}
\ No newline at end of file
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/TypeParse.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/TypeParse.java
deleted file mode 100644
index f00d707..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/function/TypeParse.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.fluent.mocker.function;
-
-import com.forte.util.parser.FieldParser;
-
-/**
- * 用于{@link com.forte.util.parser.ParameterParser}中,来注册各种参数类型的解析器。
- * 参数类型一般代表的是Map中的这个Object
- * @author ForteScarlet
- */
-@FunctionalInterface
-public interface TypeParse {
-
- /**
- * 接收部分参数,得到一个解析结果
- * @param objectClass 封装类型
- * @param fieldName 字段名称
- * @param intervalStr 区间字符串
- * @param value 参数
- * @return 字段解析器
- */
- FieldParser parse(Class> objectClass, String fieldName, String intervalStr, Object value);
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ArrayElementInvoker.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ArrayElementInvoker.java
deleted file mode 100644
index b9dcab1..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ArrayElementInvoker.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package io.fluent.mocker.invoker;
-
-import com.forte.util.utils.RandomUtil;
-
-/**
- *
- * 数组类型的{@link ElementInvoker}
- *
- * @author ForteScarlet
- * @date 2020/8/1
- */
-public class ArrayElementInvoker extends ElementInvoker {
-
- /** 集合参数 */
- private T[] arr;
- /**
- * 数组构造
- * @param arr
- */
- public ArrayElementInvoker(T[] arr){
- this.arr = arr;
- }
-
- @Override
- public T getRandomElement() {
- return RandomUtil.getRandomElement(arr);
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ElementInvoker.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ElementInvoker.java
deleted file mode 100644
index 68cd251..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ElementInvoker.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package io.fluent.mocker.invoker;
-
-import java.util.List;
-
-/**
- * 随机元素值执行者
- * 两个字段,一个有值,一个为null
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date 2018/12/7 20:37
- */
-public abstract class ElementInvoker implements Invoker {
-
- public abstract T getRandomElement();
-
- /**
- * 执行者,获取随机元素
- */
- @Override
- public Object invoke() {
- return getRandomElement();
- }
-
- public static ElementInvoker getInstance(T... array){
- return new ArrayElementInvoker<>(array);
- }
-
- public static ElementInvoker getInstance(List list){
- return new ListElementInvoker<>(list);
- }
-
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/Invoker.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/Invoker.java
deleted file mode 100644
index 0c245d7..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/Invoker.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package io.fluent.mocker.invoker;
-
-/**
- * 执行者接口,定义了一个执行者的函数,执行者会通过invoke()方法获得结果
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-@FunctionalInterface
-public interface Invoker {
-
- /**
- * 返回方法执行的结果
- * @return 获取执行结果
- * @throws Exception 可能会存在异常
- */
- Object invoke() throws Exception;
-}
-
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ListElementInvoker.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ListElementInvoker.java
deleted file mode 100644
index a6db384..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/ListElementInvoker.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.fluent.mocker.invoker;
-
-import com.forte.util.utils.RandomUtil;
-
-import java.util.List;
-
-/**
- *
- * list类型的{@link ElementInvoker}
- *
- * @author ForteScarlet
- * @date 2020/8/1
- */
-public class ListElementInvoker extends ElementInvoker {
- /** 集合参数 */
- private List list;
-
-
-
- /**
- * 集合构造
- * @param list
- */
- public ListElementInvoker(List list){
- this.list = list;
- }
-
- @Override
- public T getRandomElement() {
- return RandomUtil.getRandomElement(list);
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/MethodInvoker.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/MethodInvoker.java
deleted file mode 100644
index 310cba2..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/invoker/MethodInvoker.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package io.fluent.mocker.invoker;
-
-import com.forte.util.utils.MethodUtil;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * 方法执行者,是{@link com.forte.util.invoker.Invoker}的是实现类,代表了一个方法的执行
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- */
-public class MethodInvoker implements Invoker {
- /**
- * 执行方法的对象
- */
- private final Object obj;
- /**
- * 方法的名字
- */
- private final String methodName;
- /**
- * 方法的参数
- */
- private final Object[] args;
- /**
- * 方法的主体 - MockUtil中的静态方法
- */
- private final Method method;
-
- /**
- * 获取一个普通的{@link MethodInvoker}
- * @param obj 实例
- * @param args 参数列表
- * @param method 方法实例
- * @return {@link MethodInvoker}
- */
- public static MethodInvoker getInstance(Object obj, Object[] args, Method method){
- return new MethodInvoker(obj, args, method);
- }
-
- /**
- * 获取一个常量{@link MethodInvoker}
- * @param constValue 常量值
- * @return {@link MethodInvoker}
- */
- public static MethodInvoker getInstance(Object constValue){
- return new ConstValueMethodInvoker(constValue);
- }
-
- /**
- * 执行方法
- *
- * @return
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- */
- @Override
- public Object invoke() throws InvocationTargetException, IllegalAccessException {
- // 普通的执行者
- return MethodUtil.invoke(obj, args, method);
- }
-
- /**
- * 构造
- */
- MethodInvoker(Object obj, Object[] args, Method method) {
- this.obj = obj;
- if(method != null){
- this.methodName = method.getName();
- }else{
- this.methodName = null;
- }
- this.args = args;
- this.method = method;
- }
-
-
- /**
- * 常量值方法执行者
- */
- static class ConstValueMethodInvoker extends MethodInvoker {
- /**
- * 如果是一个空执行者,将会将对象返回
- */
- private final Object constValue;
-
- ConstValueMethodInvoker(Object constValue){
- super(null, null, null);
- this.constValue = constValue;
- }
-
- /**
- * 返回常量值
- */
- @Override
- public Object invoke() {
- return constValue;
- }
- }
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/BranchResult.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/BranchResult.java
deleted file mode 100644
index 34af1ee..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/BranchResult.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package io.fluent.mocker.loader;
-
-/**
- * 直译:分支结果
- * 代表结果有着成功与否
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date Created in 2018/12/26 17:53
- * @since JDK1.8
- **/
-public interface BranchResult extends Result {
-
- /**
- * 判断是否成功
- * @return
- */
- Boolean isSuccess();
-
- /**
- * 如果失败,为何失败
- * @return
- */
- Exception why();
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/DefaultMockMethodLoader.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/DefaultMockMethodLoader.java
deleted file mode 100644
index 9cd72f2..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/DefaultMockMethodLoader.java
+++ /dev/null
@@ -1,369 +0,0 @@
-package io.fluent.mocker.loader;
-
-import com.forte.util.Mock;
-
-import java.lang.reflect.Method;
-import java.util.*;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * 基础的假方法加载者
- * 加载的类或方法需要满足以下要求:
- *
- * 加载的方法不可与{@link com.forte.util.utils.MockUtil}中出现的方法发生方法名相同,参数数量也相同 的情况,如果发生此情况,将会抛出异常。
- * 方法必须有返回值(非void)
- *
- * ※ 本类目前不保证线程安全
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date Created in 2018/12/26 17:33
- * @since JDK1.8
- **/
-public class DefaultMockMethodLoader implements MethodLoader {
-
- /** 获取mock方法集,此时的方法集已经通过静态代码块初始化完毕 */
- private final Map MOCK_METHOD;
-
- /** 要加载的方法,方法不能重复,使用set */
- private Set waitingMethods = new HashSet<>(10);
-
- public DefaultMockMethodLoader(Map mockMethod){
- this.MOCK_METHOD = mockMethod;
- }
-
- /**
- * 根据方法名加载一个方法,如果方法名对应了多个方法,则会全部进行判断,因此可能会有多个方法
- * @param loadClz 指定类
- * @param methodName 方法名
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader append(Class loadClz, String methodName) {
- //获取全部方法
- Method[] declaredMethods = loadClz.getDeclaredMethods();
- //返回结果
- return appends(Arrays.stream(declaredMethods).filter(m -> m.getName().equals(methodName)).toArray(Method[]::new));
- }
-
- /**
- * 添加一个方法
- * @param method 要加载的方法
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader append(Method method) {
- if(can(method)){
- this.waitingMethods.add(method);
- }
- return this;
- }
-
- /**
- * 加载多个方法
- * @param methods 要加载的方法列表
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appends(Method... methods) {
- //筛选,方法名匹配且参数类型
- Set q = Arrays.stream(methods).filter(this::can).collect(Collectors.toSet());
- //添加结果
- this.waitingMethods.addAll(q);
- return this;
- }
-
- /**
- * 加载类中的全部方法
- * @param loadClz 加载方法的类
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appendAll(Class loadClz) {
- return appends(loadClz.getDeclaredMethods());
- }
-
- /**
- * 根据方法名筛选方法筛选
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appendForNameFilter(Class loadClz, Predicate predicate) {
- //先根据方法名筛选过滤
- Method[] q = Arrays.stream(loadClz.getDeclaredMethods()).filter(m -> predicate.test(m.getName())).toArray(Method[]::new);
- return appends(q);
- }
-
- /**
- * 根据方法筛选方法筛选
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appendForMethodFilter(Class loadClz, Predicate predicate) {
- //根据条件筛选
- Method[] q = Arrays.stream(loadClz.getDeclaredMethods()).filter(predicate).toArray(Method[]::new);
- return appends(q);
- }
-
- /**
- * 加载指定方法名的多个方法
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appendByNames(Class loadClz, String[] names) {
- //遍历每个名字并尝试加载
- for (String name : names) {
- append(loadClz , name);
- }
- return this;
- }
-
- /**
- * 加载指定方法名的多个方法
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appendByNames(Class loadClz, List names) {
- return appendByNames(loadClz , names.toArray(new String[0]));
- }
-
- /**
- * 根据正则规则匹配方法中的方法名
- * @param loadClz 加载方法的类
- * @param regex 正则表达式
- * @return 返回自身-链式
- */
- @Override
- public MethodLoader appendByRegex(Class loadClz, String regex) {
- return appendForNameFilter(loadClz, s -> s.matches(regex));
- }
-
- /**
- * 过滤
- * @param predicate 过滤规则
- * @return 过滤后的结果
- */
- @Override
- public MethodLoader filter(Predicate predicate) {
- //过滤并重新赋值
- waitingMethods = waitingMethods.stream().filter(predicate).collect(Collectors.toSet());
- return this;
- }
-
-
- /* ———————————————————————— 非链式方法 —————————————————————— */
-
- /**
- * 加载某类中指定方法名的方法。如果有重载方法将会全部判断
- *
- * @param loadClz 指定类
- * @param methodName 方法名
- * @return 处理结果
- */
- @Override
- public LoadResults add(Class loadClz, String methodName) {
- //获取全部方法
- Method[] declaredMethods = loadClz.getDeclaredMethods();
- //返回结果
- return adds(declaredMethods);
-
- }
-
- /**
- * 加载指定方法
- *
- * @param method 要加载的方法
- * @return 处理结果
- */
- @Override
- public LoadResults add(Method method) {
- //返回结果
- return adds(method);
- }
-
- /**
- * 直接加载方法
- *
- * @param methods 要加载的方法列表
- * @return 处理结果
- */
- @Override
- public LoadResults adds(Method... methods) {
- //筛选,方法名匹配且参数类型
- Set q = Arrays.stream(methods).filter(this::can).collect(Collectors.toSet());
-
- //直接添加方法
- return load(q);
- }
-
- /**
- * 加载class中的全部方法
- *
- * @param loadClz 加载方法的类
- * @return 处理结果
- */
- @Override
- public LoadResults addAll(Class loadClz) {
- return adds(loadClz.getDeclaredMethods());
- }
-
- /**
- * 根据匹配规则对类中的方法名进行过滤
- *
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 处理结果
- */
- @Override
- public LoadResults addForNameFilter(Class loadClz, Predicate predicate) {
- Method[] q = Arrays.stream(loadClz.getDeclaredMethods()).filter(m -> predicate.test(m.getName())).toArray(Method[]::new);
- return adds(q);
- }
-
- /**
- * 根据匹配规则对类中的方法进行过滤
- *
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 处理结果
- */
- @Override
- public LoadResults addForMethodFilter(Class loadClz, Predicate predicate) {
- //根据条件筛选
- Method[] q = Arrays.stream(loadClz.getDeclaredMethods()).filter(predicate).toArray(Method[]::new);
- return adds(q);
- }
-
- /**
- * 根据方法名列表加载class中的指定方法
- *
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 处理结果
- */
- @Override
- public LoadResults addByNames(Class loadClz, String[] names) {
- //根据名称获取全部方法
- Method[] methods = loadClz.getMethods();
- //将方法名匹配的方法留下
- Method[] endMethod = Arrays.stream(methods).filter(m -> Arrays.stream(names).anyMatch(n -> n.equals(m.getName()))).toArray(Method[]::new);
-
- //返回结果
- return adds(endMethod);
- }
-
- /**
- * 根据方法名列表加载class中的指定方法
- *
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 处理结果
- */
- @Override
- public LoadResults addByNames(Class loadClz, List names) {
- return addByNames(loadClz, names.toArray(new String[0]));
- }
-
- /**
- * 根据正则对方法名匹配并加载class中符合条件的方法
- *
- * @param loadClz 加载方法的类
- * @param regex 正则表达式
- * @return 处理结果
- */
- @Override
- public LoadResults addByRegex(Class loadClz, String regex) {
- return addForNameFilter(loadClz , s -> s.matches(regex));
- }
-
- /* ———————————————————————— 终结方法 —————————————————————— */
-
- /**
- * 要加载的内容是否为空
- * @return 是否为空
- */
- @Override
- public boolean isEmpty() {
- return waitingMethods.isEmpty();
- }
-
- /**
- * 加载
- * @return 加载结果
- */
- @Override
- public LoadResults load() {
- return load(waitingMethods);
- }
-
-
- /**
- * 将传入的方法加载至随机方法集中并返回添加结果报告
- * @param methods
- * @return
- */
- private LoadResults load(Set methods){
- //遍历要加载的方法并添加,并获取结果返回值
- Set> collect = methods.stream().flatMap(m -> {
- Map methodMap = new HashMap<>(8);
- //格式化方法名,并作为key
- String key = m.getName() + "("
- + Arrays.stream(m.getParameterTypes())
- .map(Class::getName)
- .collect(Collectors.joining(",")) +
- ")";
- methodMap.put(key, m);
-
- //添加记录
- MOCK_METHOD.put(key, m);
-
- return methodMap.entrySet().stream();
- }).map(e -> {
- //遍历所有的Entry对象
- try {
- Method put = Mock._getMockMethod().put(e.getKey(), e.getValue());
- //如果添加成功则保存
- return MockMethodLoadResult.success(put);
- } catch (Exception err) {
- //如果添加失败则返回错误
- return MockMethodLoadResult.fail(e.getValue(), err);
- }
- }).collect(Collectors.toSet());
-
- //返回结果集封装
- return new MockMethodLoadReport(collect);
- }
-
-
- /* ———————————————————————— 部分getter的api —————————————————————— */
-
-
- /**
- * 等待加载的方法集
- *
- * @return
- */
- @Override
- public Set waiting() {
- return waitingMethods;
- }
-
- /**
- * 等待加载的方法集的数量
- *
- * @return
- */
- @Override
- public int waitingNum() {
- return waitingMethods.size();
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/LoadResults.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/LoadResults.java
deleted file mode 100644
index fe330ce..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/LoadResults.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package io.fluent.mocker.loader;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * 方法加载后的返回值接口
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date Created in 2018/12/26 17:40
- * @since JDK1.8
- **/
-public interface LoadResults {
-
- /**
- * 将成功加载的结果返回
- * @return 成功结果
- */
- Set loadSuccessResults();
-
- /**
- * 将结果作为结果返回,分为成功和失败两种结果
- * @return
- */
- Map> loadResults();
-
- /**
- * 成功结果的数量
- * @return
- */
- int successNums();
-
- /**
- * 失败的结果数量
- * @return
- */
- int failNums();
-
- /**
- * 将加载错误的方法返回,并告知其失败原因
- * @return
- */
- Map whyFail();
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MethodLoader.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MethodLoader.java
deleted file mode 100644
index 68bdd5a..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MethodLoader.java
+++ /dev/null
@@ -1,245 +0,0 @@
-package io.fluent.mocker.loader;
-
-import com.forte.util.Mock;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * 假方法加载类
- * 加载的类或方法需要满足以下要求:
- *
- * 加载的方法不可与{@link com.forte.util.utils.MockUtil}中出现的方法发生方法名相同,参数数量也相同 的情况,如果发生此情况,将会抛出异常。
- * 方法必须为有返回值的(非void)
- * 方法如果存在参数,请使用引用数据类型,避免使用基本数据类型
- *
- *
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date Created in 2018/12/24 20:36
- * @version 1.1
- * @since JDK1.8
- **/
-public interface MethodLoader {
-
- /* —————————————————————————— 预载单方法 —————————————————————————— */
-
- /**
- * 加载某类中指定方法名的方法。如果有重载方法将会全部判断
- * @param loadClz 指定类
- * @param methodName 方法名
- * @return 处理结果
- */
- MethodLoader append(Class loadClz , String methodName);
-
- /**
- * 加载指定方法
- * @param method 要加载的方法
- * @return 处理结果
- */
- MethodLoader append(Method method);
-
- /* —————————————————————————— 预载多方法 —————————————————————————— */
-
- /**
- * 直接加载方法
- * @param methods 要加载的方法列表
- * @return 处理结果
- */
- MethodLoader appends(Method... methods);
-
-
- /**
- * 加载class中的全部方法
- * @param loadClz 加载方法的类
- * @return 处理结果
- */
- MethodLoader appendAll(Class loadClz);
-
- /**
- * 根据匹配规则对类中的方法名进行过滤
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 处理结果
- */
- MethodLoader appendForNameFilter(Class loadClz , Predicate predicate);
-
- /**
- * 根据匹配规则对类中的方法进行过滤
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 处理结果
- */
- MethodLoader appendForMethodFilter(Class loadClz , Predicate predicate);
-
- /**
- * 根据方法名列表加载class中的指定方法
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 处理结果
- */
- MethodLoader appendByNames(Class loadClz , String[] names);
-
- /**
- * 根据方法名列表加载class中的指定方法
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 处理结果
- */
- MethodLoader appendByNames(Class loadClz , List names);
-
- /**
- * 根据正则对方法名匹配并加载class中符合条件的方法
- * @param loadClz 加载方法的类
- * @param regex 正则表达式
- * @return 处理结果
- */
- MethodLoader appendByRegex(Class loadClz , String regex);
-
- /* —————————————————————————— 数据处理 —————————————————————————— */
-
- /**
- * 对方法进行过滤
- * @param predicate 过滤规则
- * @return 处理结果
- */
- MethodLoader filter(Predicate predicate);
-
-
- /**
- * 判断此方法是否可行
- * @param method
- * @return
- */
- default boolean can(Method method){
- //如果此方法没有返回值则直接返回false
- if(method.getReturnType().equals(void.class)){
- return false;
- }
- //获取已经加载的方法
- Map methodMap = Mock._getMockMethod();
- String keyName = method.getName() + "(" + Arrays.stream(method.getParameters()).map(p -> p.getType().getTypeName()).collect(Collectors.joining(",")) + ")";
- return methodMap.entrySet().stream().noneMatch(
- e -> keyName.equals(e.getKey())
- && (method.getParameters().length == e.getValue().getParameters().length)
- );
- }
-
-
-
- /* —————————————————————————— 加载/终结方法 —————————————————————————— */
-
-
- /**
- * 将预载内容加载至方法集
- * @return 加载成功数量
- */
- LoadResults load();
-
-
-
- /* —————————————————————————— 加载/终结方法-非链式 —————————————————————————— */
-
- /* —————————————————————————— 预载单方法 —————————————————————————— */
-
- /**
- * 加载某类中指定方法名的方法。如果有重载方法将会全部判断
- * @param loadClz 指定类
- * @param methodName 方法名
- * @return 处理结果
- */
- LoadResults add(Class loadClz , String methodName);
-
- /**
- * 加载指定方法
- * @param method 要加载的方法
- * @return 处理结果
- */
- LoadResults add(Method method);
-
- /* —————————————————————————— 预载多方法 —————————————————————————— */
-
- /**
- * 直接加载方法
- * @param methods 要加载的方法列表
- * @return 处理结果
- */
- LoadResults adds(Method... methods);
-
-
- /**
- * 加载class中的全部方法
- * @param loadClz 加载方法的类
- * @return 处理结果
- */
- LoadResults addAll(Class loadClz);
-
- /**
- * 根据匹配规则对类中的方法名进行过滤
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 处理结果
- */
- LoadResults addForNameFilter(Class loadClz , Predicate predicate);
-
- /**
- * 根据匹配规则对类中的方法进行过滤
- * @param loadClz 加载方法的类
- * @param predicate 匹配规则
- * @return 处理结果
- */
- LoadResults addForMethodFilter(Class loadClz , Predicate predicate);
-
- /**
- * 根据方法名列表加载class中的指定方法
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 处理结果
- */
- LoadResults addByNames(Class loadClz , String[] names);
-
- /**
- * 根据方法名列表加载class中的指定方法
- * @param loadClz 加载方法的类
- * @param names 方法名列表
- * @return 处理结果
- */
- LoadResults addByNames(Class loadClz , List names);
-
- /**
- * 根据正则对方法名匹配并加载class中符合条件的方法
- * @param loadClz 加载方法的类
- * @param regex 正则表达式
- * @return 处理结果
- */
- LoadResults addByRegex(Class loadClz , String regex);
-
- /* —————————————————————————— 一些getter方法等api —————————————————————————— */
-
- /**
- * 等待加载的方法集
- * @return
- */
- Set waiting();
-
- /**
- * 等待加载的方法集的数量
- * @return
- */
- int waitingNum();
-
- /**
- * 判断预载内容是否为空
- * @return 判断结果
- */
- boolean isEmpty();
-
-
-
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MockMethodLoadReport.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MockMethodLoadReport.java
deleted file mode 100644
index 4b1ed25..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MockMethodLoadReport.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package io.fluent.mocker.loader;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date 2018/12/27 17:10
- */
-public class MockMethodLoadReport implements LoadResults {
-
-
- private final Set> RESULTS;
-
- /**
- * 将成功加载的结果返回
- *
- * @return 成功结果
- */
- @Override
- public Set loadSuccessResults() {
- //获取成功的方法列表
- return RESULTS.stream().filter(BranchResult::isSuccess).map(BranchResult::getResult).collect(Collectors.toSet());
- }
-
- /**
- * 将结果作为结果返回,分为成功和失败两种结果
- * @return
- * 成功与否的结果集
- */
- @Override
- public Map> loadResults() {
- return RESULTS.stream().collect(Collectors.groupingBy(
- BranchResult::isSuccess ,
- Collectors.mapping(BranchResult::getResult , Collectors.toSet())
- ));
- }
-
- /**
- * 成功结果的数量
- * @return
- * 成功结果的数量
- */
- @Override
- public int successNums() {
- return (int) RESULTS.stream().filter(BranchResult::isSuccess).count();
- }
-
- /**
- * 失败的结果数量
- * @return 失败的结果数量
- */
- @Override
- public int failNums() {
- return (int) RESULTS.stream().filter(r -> !r.isSuccess()).count();
- }
-
- /**
- * 将加载错误的方法返回,并告知其失败原因
- * @return 错误的方法以及失败原因
- */
- @Override
- public Map whyFail() {
- return RESULTS.stream().filter(re -> !re.isSuccess()).collect(Collectors.toMap(BranchResult::getResult, BranchResult::why));
- }
-
-
-
- /**
- * 构造
- * @param results 结果集
- */
- MockMethodLoadReport(Set> results){
- this.RESULTS = results;
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MockMethodLoadResult.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MockMethodLoadResult.java
deleted file mode 100644
index 4c9df13..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/MockMethodLoadResult.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package io.fluent.mocker.loader;
-
-import java.lang.reflect.Method;
-
-/**
- * 方法的加载结果
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date Created in 2018/12/26 17:45
- * @since JDK1.8
- **/
-class MockMethodLoadResult implements BranchResult {
-
- /** 结果 */
- private final Method result;
-
- /** 如果结果为成功的结果,则为true */
- private final Boolean success;
-
- /** 如果success为false,则此字段记录的结果的失败原因(异常) */
- private final Exception why;
-
-
- @Override
- public Boolean isSuccess() {
- return this.success;
- }
-
- @Override
- public Exception why() {
- return this.why;
- }
-
- @Override
- public Method getResult() {
- return this.result;
- }
-
- /**
- * 工厂方法。获得一个成功的返回值
- * @param result 结果
- * @return 返回一个实例
- */
- public static MockMethodLoadResult success(Method result){
- return new MockMethodLoadResult(result , true , null);
- }
-
- /**
- * 工厂方法。获得一个失败的返回值
- * @param result 结果
- * @param why 为何失败
- * @return 返回一个实例
- */
- public static MockMethodLoadResult fail(Method result , Exception why){
- return new MockMethodLoadResult(result , false, why);
- }
-
- /**
- * 唯一私有构造
- * @param result 结果
- * @param success 是否成功
- * @param why 为何失败
- */
- private MockMethodLoadResult(Method result, Boolean success, Exception why){
- this.result = result;
- this.success = success;
- this.why = why;
- }
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/Result.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/Result.java
deleted file mode 100644
index 7a1481a..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/loader/Result.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.fluent.mocker.loader;
-
-/**
- * 方法的返回结果
- * @author ForteScarlet <[163邮箱地址]ForteScarlet@163.com>
- * @date Created in 2018/12/26 17:48
- * @since JDK1.8
- **/
-public interface Result {
-
-
- /**
- * 获取结果
- * @return 结果
- */
- T getResult();
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/ArrayMapper.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/ArrayMapper.java
deleted file mode 100644
index 5d2a8fb..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/ArrayMapper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.fluent.mocker.mapper;
-
-import java.util.Arrays;
-import java.util.function.Function;
-import java.util.function.IntFunction;
-
-/**
- * 映射器,可以指定将字符串数组内的值转化为其他类型
- * 需要存在一个无参构造
- * @author ForteScarlet <[email]ForteScarlet@163.com>
- * @since JDK1.8
- **/
-public interface ArrayMapper extends Function {
-
- /**
- * 给你一个数组长度,返回一个数组实例的function,用于数组的实例化获取
- * @return 数组实例获取函数
- */
- IntFunction getArrayParseFunction();
-
- /**
- * 进行转化, 将String类型的数组转化为某指定类型
- * @param array String array
- */
- default T[] map(String[] array){
- //真正被使用的对外接口
- return Arrays.stream(array).map(this).toArray(this.getArrayParseFunction());
- }
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/ArrayMapperType.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/ArrayMapperType.java
deleted file mode 100644
index f13bdfd..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/ArrayMapperType.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package io.fluent.mocker.mapper;
-
-import java.util.function.IntFunction;
-
-/**
- * 部分指定好的转化器类型
- * 接口类型,内部提供部分ArrayMapper实现类
- * @author ForteScarlet <[email]ForteScarlet@163.com>
- * @since JDK1.8
- **/
-public interface ArrayMapperType {
-
-// /** 转化为String类型 */
-// Class TO_STRING = ToString.class;
-//
-// /** 转化为Integer类型 */
-// Class TO_INT = ToInt.class;
-//
-// /** 转化为Double类型 */
-// Class TO_DOUBLE = ToDouble.class;
-//
-// /** 转化为Long类型 */
-// Class TO_LONG = ToLong.class;
-
- /**
- * 保持String类型不变
- */
- class ToString implements ArrayMapper {
-
- @Override
- public IntFunction getArrayParseFunction() {
- return String[]::new;
- }
-
- @Override
- public String apply(String s) {
- return s;
- }
- }
-
- /**
- * 转化为Int类型
- */
- class ToInt implements ArrayMapper {
- @Override
- public Integer apply(String s) {
- return Integer.parseInt(s);
- }
- @Override
- public IntFunction getArrayParseFunction() {
- return Integer[]::new;
- }
- }
-
- /**
- * 转化为Double类型
- */
- class ToDouble implements ArrayMapper {
- @Override
- public IntFunction getArrayParseFunction() {
- return Double[]::new;
- }
-
- @Override
- public Double apply(String s) {
- return Double.parseDouble(s);
- }
- }
-
- /**
- * 转化为Long类型
- */
- class ToLong implements ArrayMapper {
-
- @Override
- public IntFunction getArrayParseFunction() {
- return Long[]::new;
- }
-
- @Override
- public Long apply(String s) {
- return Long.parseLong(s);
- }
- }
-
-
-
-
-
-
-
-
-
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockArray.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockArray.java
deleted file mode 100644
index 89ef0c1..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockArray.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package io.fluent.mocker.mapper;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- *
- * 数组类型的注解,类型为整数类型,
- * 可以指定一个转化规则使得这个字符串数组可以转化为其他类型
- *
- * @author ForteScarlet <[email]ForteScarlet@163.com>
- * @since JDK1.8
- **/
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD) //字段
-public @interface MockArray {
-
- /**
- * 数组参数
- */
- String[] value();
-
- /**
- * 类型转化器实现类,需要存在无参构造
- * 默认不变
- */
- Class extends ArrayMapper> mapper() default ArrayMapperType.ToString.class;
-
-
- /**
- * 区间参数,如果有值,则代表了字段之前的区间参数。默认没有值
- * 例如当字段{@code age} 的注解参数为 {@code param = "10-20"} 的时候, 相当于字段值为{@code "age|10-20"}。参数中的那个竖线不需要写。写了也会被去除的。
- * @since 1.6.0
- */
- String param() default "";
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockBean.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockBean.java
deleted file mode 100644
index 19e7423..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockBean.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.fluent.mocker.mapper;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 当进行包扫描的时候,会扫描到所有标记了此注解的类
- * 暂时没有参数,仅用作标记用。
- * @author ForteScarlet
- */
-@Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到
-@Target({ElementType.TYPE}) //类
-public @interface MockBean {
-}
diff --git a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockProxy.java b/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockProxy.java
deleted file mode 100644
index 517a10f..0000000
--- a/modules/fluent-mocker/src/main/java/io/fluent/mocker/mapper/MockProxy.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package io.fluent.mocker.mapper;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Mock接口代理注解标识,标记在接口的抽象方法上。抽象方法
- * @author ForteScarlet
- */
-@Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到
-@Target({ElementType.METHOD}) //接口、类、枚举、注解、方法
-public @interface MockProxy {
-
- /**
- * 是否忽略此方法。如果为是,则接口的最终代理结果为返回一个null。
- * 当然,如果获取不到对应的Mock类型,无论是否忽略都会返回null或者默认值。
- * 如果是基础数据类型相关,数字类型,返回{@code 0}。
- * 如果是基础数据类型相关,char类型,返回{@code ' '}。
- * 如果是基础数据类型相关,boolean类型,返回{@code false}。
- */
- boolean ignore() default false;
-
- /**
- * 如果此参数存在值,则会优先尝试通过name获取MockObject对象
- */
- String name() default "";
-
- /**
- * 当接口返回值为数组或者集合的时候,此方法标记其返回值数量大小区间{@code [min, max], 即 max >= size >= min}。是数学上的闭区间。
- * 如果此参数长度为0,则返回值为1。
- *