Mercurial > pub > ModelGenerator
comparison xslt/model.xsl @ 2:035de8b7b18e
Temporary commit, refactoring, added readme
author | cin |
---|---|
date | Sun, 25 Feb 2018 17:12:33 +0300 |
parents | |
children | 437127ab6a12 |
comparison
equal
deleted
inserted
replaced
1:7f803979305f | 2:035de8b7b18e |
---|---|
1 <?xml version="1.0" encoding="UTF-8"?> | |
2 <xsl:stylesheet version="1.0" | |
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://implab.org/schemas/data-model.v1.xsd" | |
4 xmlns:clr="http://implab.org/schemas/data-model/dotnet.v1.xsd" | |
5 xmlns:cs="http://implab.org/schemas/code-dom/csharp.v1.xsd" xmlns:sql="http://implab.org/schemas/data-model/sql.v1.xsd" | |
6 xmlns:t="http://implab.org/schemas/temp" xmlns:exsl="http://exslt.org/common" | |
7 exclude-result-prefixes="clr m xsl exsl sql"> | |
8 | |
9 <xsl:import href="preprocess.xsl" /> | |
10 <xsl:include href="text-tools.xsl"/> | |
11 | |
12 <xsl:output method="xml" indent="yes" /> | |
13 | |
14 <xsl:key name="type" match="m:package/m:*" use="@name" /> | |
15 | |
16 <xsl:template match="/"> | |
17 <cs:document> | |
18 <xsl:apply-templates select="$module" mode="document" /> | |
19 </cs:document> | |
20 </xsl:template> | |
21 | |
22 <!-- code generation --> | |
23 | |
24 <!-- disable default template --> | |
25 <xsl:template match="*|text()" mode="document" /> | |
26 | |
27 <xsl:template match="t:module" mode="document"> | |
28 <xsl:apply-templates mode="document" /> | |
29 </xsl:template> | |
30 | |
31 <!-- generate code for primary package --> | |
32 <xsl:template match="m:package[@primary='true' and @clr:namespace]" mode="document"> | |
33 <cs:namespace name="{@clr:namespace}"> | |
34 <xsl:apply-templates mode="document" /> | |
35 </cs:namespace> | |
36 </xsl:template> | |
37 | |
38 <xsl:template match="m:package[@primary='true']" mode="document"> | |
39 <xsl:apply-templates mode="document" /> | |
40 </xsl:template> | |
41 | |
42 <!-- member resolution traits --> | |
43 | |
44 <!-- Resolves members using given criteria | |
45 @param type | |
46 the name of the type whose members are inspected | |
47 @param memberName | |
48 the name of the member to lookup | |
49 @param scope | |
50 the scope where to look (members, properties, keys, relations) | |
51 | |
52 This template recursively inspects the given type down to it's inheritance | |
53 hierarchy and outputs members matching criteria. | |
54 --> | |
55 <xsl:template name="getMembers"> | |
56 <xsl:param name="type"/> | |
57 <xsl:param name="memberName" select="''"/> | |
58 <xsl:param name="scope" select="'members'"/> | |
59 <!-- prevents cyclic references --> | |
60 <xsl:param name="seen" select="/.."/> | |
61 <xsl:for-each select="$module"> | |
62 <xsl:apply-templates select="key('type', $type)" | |
63 mode="lookup-members"> | |
64 <xsl:with-param name="memberName" select="$memberName"/> | |
65 <xsl:with-param name="scope" select="$scope"/> | |
66 <xsl:with-param name="seen" select="$seen"/> | |
67 </xsl:apply-templates> | |
68 </xsl:for-each> | |
69 </xsl:template> | |
70 | |
71 <xsl:template match="*" mode="lookup-members"/> | |
72 | |
73 <xsl:template match="m:entity" mode="lookup-members"> | |
74 <xsl:param name="memberName" select="''"/> | |
75 <xsl:param name="scope" select="'members'"/> | |
76 <xsl:param name="seen"/> | |
77 | |
78 <xsl:variable name="self" select="."/> | |
79 | |
80 <xsl:if test="not($seen[generate-id() = generate-id($self)])"> | |
81 <xsl:variable name="scopeMembers"> | |
82 <xsl:call-template name="selectScopeMembers"> | |
83 <xsl:with-param name="scope" select="$scope"/> | |
84 </xsl:call-template> | |
85 </xsl:variable> | |
86 | |
87 <xsl:variable name="members" select="exsl:node-set($scopeMembers)/*[not($memberName) or @name='$memberName']"/> | |
88 | |
89 <xsl:choose> | |
90 <xsl:when test="$members"> | |
91 <xsl:copy-of select="$members"/> | |
92 </xsl:when> | |
93 <xsl:when test="m:extends"> | |
94 <xsl:call-template name="getMembers"> | |
95 <xsl:with-param name="type" select="m:extends/@type"/> | |
96 <xsl:with-param name="memberName" select="$memberName"/> | |
97 <xsl:with-param name="scope" select="$scope"/> | |
98 <xsl:with-param name="seen" select="$seen | $self"/> | |
99 </xsl:call-template> | |
100 </xsl:when> | |
101 <xsl:otherwise> | |
102 <xsl:call-template name="warn"> | |
103 <xsl:with-param name="msg"> | |
104 <t:trace msg="failed to resolve {$member}"/> | |
105 <t:trace msg="inspected classes"> | |
106 <xsl:for-each select="$seen | $self"> | |
107 <t:trace msg="{name()} {@name}"/> | |
108 </xsl:for-each> | |
109 </t:trace> | |
110 </xsl:with-param> | |
111 </xsl:call-template> | |
112 </xsl:otherwise> | |
113 </xsl:choose> | |
114 </xsl:if> | |
115 </xsl:template> | |
116 | |
117 <!-- this template implements scope filtering --> | |
118 <xsl:template name="selectScopeMembers"> | |
119 <xsl:param name="scope" select="'members'"/> | |
120 <xsl:choose> | |
121 <xsl:when test="$scope='members'"> | |
122 <xsl:apply-templates mode="filter-members"/> | |
123 </xsl:when> | |
124 <xsl:when test="$scope='keys'"> | |
125 <xsl:apply-template mode="filter-keys"/> | |
126 </xsl:when> | |
127 <xsl:when test="$scope='properties'"> | |
128 <xsl:apply-templates mode="fiflter-properties"/> | |
129 </xsl:when> | |
130 <xsl:when test="$scope='relations'"> | |
131 <xsl:apply-templates mode="fiflter-relations"/> | |
132 </xsl:when> | |
133 </xsl:choose> | |
134 </xsl:template> | |
135 | |
136 <!-- filter-members --> | |
137 <xsl:template match="*|text()" mode="filter-members"/> | |
138 <xsl:template match="*[@name]" mode="filter-members"> | |
139 <xsl:copy> | |
140 <xsl:copy-of select="@*" /> | |
141 <xsl:attribute name="declaringType"><xsl:value-of select="../@name" /></xsl:attribute> | |
142 <xsl:copy-of select="*" /> | |
143 </xsl:copy> | |
144 </xsl:template> | |
145 | |
146 <!-- filter-keys --> | |
147 <xsl:template match="*|text()" mode="filter-keys"/> | |
148 <xsl:template match="m:primaryKey" mode="filter-keys"> | |
149 <xsl:apply-templates select="." mode="filter-members"/> | |
150 </xsl:template> | |
151 | |
152 <!-- filter-properties --> | |
153 <xsl:template match="*|text()" mode="filter-properties"/> | |
154 <xsl:template match="m:property" mode="filter-properties"> | |
155 <xsl:apply-templates select="." mode="filter-members"/> | |
156 </xsl:template> | |
157 | |
158 <!-- filter-relations --> | |
159 <xsl:template match="*|text()" mode="filter-relations"/> | |
160 <xsl:template match="m:hasA | m:hasMany" mode="filter-relations"> | |
161 <xsl:apply-templates select="." mode="filter-members"/> | |
162 </xsl:template> | |
163 | |
164 | |
165 | |
166 <!-- primary key --> | |
167 | |
168 <!-- Resolves primaryKey information for the given type name. | |
169 @returns m:primaryKey node copy with additional attribute | |
170 @declaringType which points to the type where this primaryKey | |
171 was defined. | |
172 --> | |
173 <xsl:template name="getPrimaryKey"> | |
174 <xsl:param name="type" /> | |
175 <xsl:call-template name="getMembers"> | |
176 <xsl:with-param name="type" select="$type"/> | |
177 <xsl:with-param name="scope" select="keys"/> | |
178 </xsl:call-template> | |
179 </xsl:template> | |
180 | |
181 <!-- --> | |
182 <xsl:template name="getKeyType"> | |
183 <xsl:param name="type" /> | |
184 <xsl:variable name="otherKey"> | |
185 <xsl:call-template name="getKey"> | |
186 <xsl:with-param name="type" select="$type" /> | |
187 </xsl:call-template> | |
188 </xsl:variable> | |
189 <xsl:apply-templates select="exsl:node-set($otherKey)/m:primaryKey" mode="property-type"/> | |
190 </xsl:template> | |
191 | |
192 <xsl:template name="getKeyName"> | |
193 <xsl:param name="type" /> | |
194 <xsl:variable name="otherKey"> | |
195 <xsl:call-template name="getKey"> | |
196 <xsl:with-param name="type" select="$type" /> | |
197 </xsl:call-template> | |
198 </xsl:variable> | |
199 <xsl:apply-templates select="exsl:node-set($otherKey)/m:primaryKey" mode="property-name"/> | |
200 </xsl:template> | |
201 | |
202 <!-- internal. applied to the entity with a primaryKey node --> | |
203 <xsl:template match="m:entity[m:primaryKey]" mode="resolvePK"> | |
204 <xsl:apply-templates select="m:primaryKey" mode="resolvePK" /> | |
205 </xsl:template> | |
206 | |
207 <!-- | |
208 This template formats the result of 'resolvePk' template, | |
209 override this template to extend returned metadata, beware that | |
210 other templates rely on the resulting format of this template. | |
211 --> | |
212 <xsl:template match="m:primaryKey" mode="resolvePK"> | |
213 <xsl:copy> | |
214 <xsl:copy-of select="@*" /> | |
215 <xsl:attribute name="declaringType"><xsl:value-of select="../@name" /></xsl:attribute> | |
216 <xsl:copy-of select="*" /> | |
217 </xsl:copy> | |
218 </xsl:template> | |
219 | |
220 <!-- internal, used to traverse the hierarchy --> | |
221 <xsl:template match="m:entity" mode="resolvePK"> | |
222 <xsl:apply-templates select="m:extends" mode="resolvePK" /> | |
223 </xsl:template> | |
224 | |
225 <!-- internal, used to traverse the hierarchy --> | |
226 <xsl:template match="m:extends" mode="resolvePK"> | |
227 <xsl:apply-templates select="key('type', @type)" | |
228 mode="resolvePK" /> | |
229 </xsl:template> | |
230 | |
231 <!-- resolves CLR type for the given type --> | |
232 <xsl:template name="getClrType"> | |
233 <xsl:param name="type" /> | |
234 <xsl:param name="typeArgs" select="/.." /> | |
235 <!-- <t:trace msg="resolveClrType {$type}"/> --> | |
236 <xsl:for-each select="$module"> | |
237 <xsl:apply-templates select="key('type', $type)" | |
238 mode="clr-type"> | |
239 <xsl:with-param name="typeArgs" select="$typeArgs"/> | |
240 </xsl:apply-templates> | |
241 </xsl:for-each> | |
242 </xsl:template> | |
243 | |
244 <!-- CLR type construction --> | |
245 <xsl:template match="*" mode="clr-type" /> | |
246 | |
247 <xsl:template match="m:type[clr:type]" mode="clr-type"> | |
248 <xsl:param name="typeArgs" select="clr:type/*" /> | |
249 <xsl:apply-templates select="clr:type" mode="clr-type"> | |
250 <xsl:with-param name="typeArgs" select="$typeArgs" /> | |
251 </xsl:apply-templates> | |
252 </xsl:template> | |
253 | |
254 <xsl:template match="m:entity" mode="clr-type"> | |
255 <cs:type name="{@clr:name | @name[not(../@clr:name)]}" namespace="{ancestor::*[@clr:namespace]/@clr:namespace}" /> | |
256 </xsl:template> | |
257 | |
258 <xsl:template match="clr:type" mode="clr-type"> | |
259 <xsl:apply-templates mode="clr-type"/> | |
260 </xsl:template> | |
261 | |
262 <xsl:template match="clr:type[@ref]" mode="clr-type"> | |
263 <xsl:param name="typeArgs" select="*" /> | |
264 <xsl:call-template name="getClrType"> | |
265 <xsl:with-param name="type" select="@ref" /> | |
266 <xsl:with-param name="typeArgs" select="$typeArgs" /> | |
267 </xsl:call-template> | |
268 </xsl:template> | |
269 | |
270 <xsl:template match="clr:type[@cs:name or @name]" mode="clr-type"> | |
271 <xsl:param name="typeArgs" select="*" /> | |
272 <xsl:variable name="ns" | |
273 select="@cs:namespace | @namespace[not(../@cs:namespace)]" /> | |
274 <cs:type name="{@cs:name | @name[not(../@cs:name)]}"> | |
275 <xsl:if test="$ns"> | |
276 <xsl:attribute name="namespace"><xsl:value-of select="$ns" /></xsl:attribute> | |
277 </xsl:if> | |
278 <xsl:copy-of select="@struct"/> | |
279 | |
280 <xsl:apply-templates select="$typeArgs | *[not($typeArgs)]" | |
281 mode="clr-type" /> | |
282 </cs:type> | |
283 </xsl:template> | |
284 | |
285 <xsl:template match="clr:arrayOf[@type]" mode="clr-type"> | |
286 <xsl:param name="typeArgs" select="*" /> | |
287 <cs:array> | |
288 <xsl:call-template name="getClrType"> | |
289 <xsl:with-param name="type" select="@type" /> | |
290 <xsl:with-param name="typeArgs" select="$typeArgs" /> | |
291 </xsl:call-template> | |
292 </cs:array> | |
293 </xsl:template> | |
294 | |
295 <xsl:template match="clr:arrayOf[@cs:name or @name]" mode="clr-type"> | |
296 <xsl:param name="typeArgs" select="*" /> | |
297 <xsl:variable name="ns" | |
298 select="@cs:namespace | @namespace[not(../@cs:namespace)]" /> | |
299 <cs:array> | |
300 <cs:type name="{@cs:name | @name[not(../@cs:name)]}"> | |
301 <xsl:if test="$ns"> | |
302 <xsl:attribute name="namespace"><xsl:value-of | |
303 select="$ns" /></xsl:attribute> | |
304 </xsl:if> | |
305 <xsl:apply-templates select="$typeArgs | *[not($typeArgs)]" | |
306 mode="clr-type" /> | |
307 </cs:type> | |
308 </cs:array> | |
309 </xsl:template> | |
310 | |
311 | |
312 </xsl:stylesheet> |