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>