Skip to content

Commit b171879

Browse files
committed
docs: synced via GitHub Actions
1 parent 10cf95a commit b171879

File tree

1 file changed

+255
-0
lines changed

1 file changed

+255
-0
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# 自定义DSL模型开发指南
2+
3+
Nop平台基于可逆计算理论,提供了一套完整的机制来简化自定义DSL(领域特定语言)模型的开发。本指南通过一个完整的示例,演示如何开发一个简单的DSL模型并注册它的加载器。
4+
5+
## 1. 项目结构概览
6+
7+
在开始之前,先了解完整的项目结构:
8+
9+
您说得对,`precompile``src` 应该是平级目录。以下是修正后的项目结构:
10+
11+
```
12+
project-root/
13+
├── src/
14+
│ └── main/
15+
│ ├── resources/
16+
│ │ └── _vfs/
17+
│ │ ├── schema/
18+
│ │ │ └── simple.xdef # DSL元模型定义
19+
│ │ ├── nop/core/registry/
20+
│ │ │ └── simple.register-model.xml # 模型注册配置
21+
│ │ └── simple/
22+
│ │ └── test.simple # 自定义格式
23+
│ │ └── test.simple.xml # XML文件
24+
│ └── java/
25+
│ └── test/simple/ # 生成的Java模型类
26+
├── precompile/
27+
│ └── gen-dsl.xgen # 代码生成配置
28+
└── pom.xml # Maven构建配置
29+
```
30+
31+
## 2. 定义元模型 `simple.xdef`
32+
33+
`_vfs`目录下创建 `/simple/simple.xdef` 元模型定义文件:
34+
35+
```xml
36+
<?xml version="1.0" encoding="UTF-8"?>
37+
<simple name="!string"
38+
x:schema="/nop/schema/xdef.xdef"
39+
xmlns:x="/nop/schema/xdsl.xdef"
40+
xdef:bean-package="test.simple"
41+
xdef:name="SimpleModel">
42+
43+
<description xdef:value="string"/>
44+
45+
<columns xdef:body-type="list" xdef:key-attr="name">
46+
<column name="!string" displayName="string" type="!string" xdef:name="SimpleColumnName"/>
47+
</columns>
48+
49+
</simple>
50+
```
51+
52+
**关键属性说明:**
53+
54+
- `x:schema="/nop/schema/xdef.xdef"`:指定此文件遵循xdef元模型规范
55+
- `xdef:bean-package="test.simple"`:生成的Java类包名
56+
- `xdef:name="SimpleModel"`:生成的Java类名
57+
- `xdef:key-attr="name"`:指定name属性作为唯一标识
58+
- `!string`:表示该属性必填且为字符串类型
59+
60+
**结构定义:**
61+
62+
- `description`:模型描述信息
63+
- `columns`:列表示例属性
64+
65+
## 3. 注册模型加载器
66+
67+
`_vfs`目录下创建 `/nop/core/registry/simple.register-model.xml`
68+
69+
```xml
70+
<?xml version="1.0" encoding="UTF-8"?>
71+
<model x:schema="/nop/schema/register-model.xdef"
72+
xmlns:x="/nop/schema/xdsl.xdef"
73+
name="simple">
74+
75+
76+
<loaders>
77+
<!-- 基于XDef的解析器,用于simple.xml文件 -->
78+
<xdsl-loader fileType="simple.xml" xdefPath="/schema/simple.xdef"/>
79+
80+
<!-- 自定义解析器,用于simple文件 -->
81+
<loader fileType="simple"
82+
class="io.nop.xlang.xdsl.SimpleDslParser"
83+
returnXNode="true"/>
84+
</loaders>
85+
86+
</model>
87+
```
88+
89+
**配置说明:**
90+
91+
- **name="simple"**:DSL模型名称,在系统中唯一标识
92+
- **xdsl-loader**:基于xdef定义的通用解析器,处理XML格式
93+
- **自定义loader**:通过Java类处理特定格式,`returnXNode="true"`表示返回XNode语法树
94+
95+
## 4. 实现自定义解析器
96+
97+
创建Java解析器类 `io.nop.xlang.xdsl.SimpleDslParser`
98+
99+
```java
100+
public class SimpleDslParser implements IResourceParser<XNode> {
101+
private static final Logger LOG = LoggerFactory.getLogger(SimpleDslParser.class);
102+
103+
@Override
104+
public XNode parseResource(IResource resource) {
105+
...
106+
}
107+
}
108+
```
109+
110+
## 5. 创建DSL示例文件
111+
112+
创建XML格式的示例 `/simple/test.simple.xml`
113+
114+
```xml
115+
<?xml version="1.0" encoding="UTF-8"?>
116+
<simple name="testApp" xmlns:x="/nop/schema/xdsl.xdef" x:schema="/schema/simple.xdef">
117+
118+
<description>测试应用程序配置</description>
119+
120+
<columns>
121+
<column name="id" displayName="ID" type="Long"/>
122+
<column name="fieldA" displayName="Field A" type="String"/>
123+
124+
</columns>
125+
126+
127+
</simple>
128+
```
129+
130+
## 6. 代码生成配置
131+
132+
`precompile/gen-dsl.xgen` 中配置代码生成:
133+
134+
```xml
135+
136+
<c:script>
137+
codeGenerator.renderModel('/schema/simple.xdef','/nop/templates/xdsl', '/',$scope);
138+
</c:script>
139+
```
140+
141+
根据`simple.xdef`元模型生成模型对象,使用`_vfs`目录下的`/nop/templates/xdsl`目录下的代码生成模板。
142+
143+
## 7. Maven构建配置
144+
145+
`pom.xml` 中配置代码生成:
146+
147+
```xml
148+
<?xml version="1.0" encoding="UTF-8"?>
149+
<project xmlns="http://maven.apache.org/POM/4.0.0"
150+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
151+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
152+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
153+
154+
<parent>
155+
<artifactId>nop-entropy</artifactId>
156+
<groupId>io.github.entropy-cloud</groupId>
157+
<version>2.0.0-SNAPSHOT</version>
158+
</parent>
159+
160+
<build>
161+
<plugins>
162+
<plugin>
163+
<groupId>org.codehaus.mojo</groupId>
164+
<artifactId>exec-maven-plugin</artifactId>
165+
<executions>
166+
<execution>
167+
<id>codegen</id>
168+
<phase>generate-sources</phase>
169+
<goals>
170+
<goal>java</goal>
171+
</goals>
172+
<configuration>
173+
<mainClass>io.nop.codegen.CodeGenTask</mainClass>
174+
<arguments>
175+
<argument>precompile</argument>
176+
</arguments>
177+
</configuration>
178+
</execution>
179+
</executions>
180+
</plugin>
181+
</plugins>
182+
</build>
183+
184+
<dependencies>
185+
<dependency>
186+
<groupId>io.github.entropy-cloud</groupId>
187+
<artifactId>nop-xlang</artifactId>
188+
</dependency>
189+
<dependency>
190+
<groupId>io.github.entropy-cloud</groupId>
191+
<artifactId>nop-core</artifactId>
192+
</dependency>
193+
</dependencies>
194+
195+
</project>
196+
```
197+
198+
## 8. 使用DSL模型
199+
200+
### Java代码中加载DSL:
201+
202+
```java
203+
// 方式1:使用统一资源管理器加载
204+
SimpleModel model = (SimpleModel) ResourceComponentManager.instance()
205+
.loadComponentModel("/simple/test.simple");
206+
207+
// 方式2:直接解析XML格式
208+
SimpleModel model2 = (SimpleModel) ResourceComponentManager.instance()
209+
.loadComponentModel("/simple/test.simple.xml");
210+
211+
// 使用模型数据
212+
System.out.println("应用名称: "+model.getName());
213+
214+
```
215+
216+
调试模式下Nop平台解析DSL文件得到XNode后(此过程会执行Delta合并),会将最终结果输出到`_dump`目录下。
217+
218+
### 手动触发代码生成:
219+
220+
```java
221+
public class CodeGenerator {
222+
public static void main(String[] args) {
223+
File projectDir = new File(".");
224+
XCodeGenerator.runPrecompile(projectDir, "/", false);
225+
System.out.println("代码生成完成!");
226+
}
227+
}
228+
```
229+
230+
## 9. 核心概念总结
231+
232+
### 可逆计算理论应用:
233+
234+
1. **差量(∆)定制**:通过自定义解析器扩展基础解析能力
235+
2. **模型驱动**:从xdef元模型自动生成Java代码,保证类型安全
236+
3. **统一抽象**:不同格式的文件(.simple和.simple.xml)解析为同一模型
237+
238+
### 文件类型识别规则:
239+
240+
- `app.simple.xml``simple.xml`
241+
- `config.simple``simple`
242+
- `User.xmeta``xmeta`
243+
244+
### 解析流程:
245+
246+
```
247+
test.simple
248+
→ SimpleDslParser (自定义解析逻辑)
249+
→ 返回XNode语法树
250+
→ DslModelParser (根据xdef验证和转换)
251+
→ SimpleModel Java对象
252+
```
253+
254+
### 弱类型对象
255+
如果不想生成强类型的模型对象,可以不配置代码生成器,`simple.xdef`上不要指定`xdef:bean-package`。这种情况下解析结果是DynamicObject对象,类似于JSON对象。

0 commit comments

Comments
 (0)