Mercurial > pub > ModelGenerator
annotate xslt/model.xsl @ 12:191b81b2052b
first version of the xslt transform from xml to json
| author | cin |
|---|---|
| date | Mon, 09 Apr 2018 06:43:46 +0300 |
| parents | 19a8a71eaa54 |
| children |
| rev | line source |
|---|---|
| 2 | 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:t="http://implab.org/schemas/temp" xmlns:exsl="http://exslt.org/common" | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
5 exclude-result-prefixes="m xsl exsl"> |
| 2 | 6 |
| 7 <xsl:import href="preprocess.xsl" /> | |
| 8 <xsl:include href="text-tools.xsl"/> | |
| 9 | |
| 10 <xsl:output method="xml" indent="yes" /> | |
| 11 | |
| 12 <xsl:key name="type" match="m:package/m:*" use="@name" /> | |
| 13 | |
| 14 <xsl:template match="/"> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
15 <xsl:apply-templates select="$module" mode="document" /> |
| 2 | 16 </xsl:template> |
| 17 | |
| 18 <!-- code generation --> | |
| 19 | |
| 20 <!-- disable default template --> | |
| 21 <xsl:template match="*|text()" mode="document" /> | |
| 22 | |
| 23 <xsl:template match="t:module" mode="document"> | |
| 24 <xsl:apply-templates mode="document" /> | |
| 25 </xsl:template> | |
| 26 | |
| 3 | 27 |
| 2 | 28 |
| 29 <!-- member resolution traits --> | |
| 30 | |
| 31 <!-- Resolves members using given criteria | |
| 32 @param type | |
| 33 the name of the type whose members are inspected | |
| 34 @param memberName | |
| 35 the name of the member to lookup | |
| 36 @param scope | |
| 37 the scope where to look (members, properties, keys, relations) | |
| 38 | |
| 39 This template recursively inspects the given type down to it's inheritance | |
| 40 hierarchy and outputs members matching criteria. | |
| 41 --> | |
| 42 <xsl:template name="getMembers"> | |
| 43 <xsl:param name="type"/> | |
| 44 <xsl:param name="memberName" select="''"/> | |
| 45 <xsl:param name="scope" select="'members'"/> | |
| 46 <!-- prevents cyclic references --> | |
| 47 <xsl:param name="seen" select="/.."/> | |
| 48 <xsl:for-each select="$module"> | |
| 49 <xsl:apply-templates select="key('type', $type)" | |
| 50 mode="lookup-members"> | |
| 51 <xsl:with-param name="memberName" select="$memberName"/> | |
| 52 <xsl:with-param name="scope" select="$scope"/> | |
| 53 <xsl:with-param name="seen" select="$seen"/> | |
| 54 </xsl:apply-templates> | |
| 55 </xsl:for-each> | |
| 56 </xsl:template> | |
| 57 | |
| 58 <xsl:template match="*" mode="lookup-members"/> | |
| 59 | |
| 60 <xsl:template match="m:entity" mode="lookup-members"> | |
| 61 <xsl:param name="memberName" select="''"/> | |
| 62 <xsl:param name="scope" select="'members'"/> | |
| 63 <xsl:param name="seen"/> | |
| 64 | |
| 65 <xsl:variable name="self" select="."/> | |
| 66 | |
| 67 <xsl:if test="not($seen[generate-id() = generate-id($self)])"> | |
| 68 <xsl:variable name="scopeMembers"> | |
| 69 <xsl:call-template name="selectScopeMembers"> | |
| 70 <xsl:with-param name="scope" select="$scope"/> | |
| 71 </xsl:call-template> | |
| 72 </xsl:variable> | |
| 73 | |
| 6 | 74 <xsl:variable name="members" select="exsl:node-set($scopeMembers)/*[not($memberName) or @name=$memberName]"/> |
| 2 | 75 |
| 76 <xsl:choose> | |
| 77 <xsl:when test="$members"> | |
| 78 <xsl:copy-of select="$members"/> | |
| 79 </xsl:when> | |
| 80 <xsl:when test="m:extends"> | |
| 81 <xsl:call-template name="getMembers"> | |
| 82 <xsl:with-param name="type" select="m:extends/@type"/> | |
| 83 <xsl:with-param name="memberName" select="$memberName"/> | |
| 84 <xsl:with-param name="scope" select="$scope"/> | |
| 85 <xsl:with-param name="seen" select="$seen | $self"/> | |
| 86 </xsl:call-template> | |
| 87 </xsl:when> | |
| 88 <xsl:otherwise> | |
| 89 <xsl:call-template name="warn"> | |
| 90 <xsl:with-param name="msg"> | |
| 6 | 91 <t:trace msg="failed to resolve {$memberName}, scope={$scope}"/> |
| 2 | 92 <t:trace msg="inspected classes"> |
| 93 <xsl:for-each select="$seen | $self"> | |
| 94 <t:trace msg="{name()} {@name}"/> | |
| 95 </xsl:for-each> | |
| 96 </t:trace> | |
| 97 </xsl:with-param> | |
| 98 </xsl:call-template> | |
| 99 </xsl:otherwise> | |
| 100 </xsl:choose> | |
| 101 </xsl:if> | |
| 102 </xsl:template> | |
| 103 | |
| 104 <!-- this template implements scope filtering --> | |
| 105 <xsl:template name="selectScopeMembers"> | |
| 106 <xsl:param name="scope" select="'members'"/> | |
| 107 <xsl:choose> | |
| 108 <xsl:when test="$scope='members'"> | |
| 109 <xsl:apply-templates mode="filter-members"/> | |
| 110 </xsl:when> | |
| 111 <xsl:when test="$scope='keys'"> | |
| 6 | 112 <xsl:apply-templates mode="filter-keys"/> |
| 2 | 113 </xsl:when> |
| 114 <xsl:when test="$scope='properties'"> | |
| 115 <xsl:apply-templates mode="fiflter-properties"/> | |
| 116 </xsl:when> | |
| 117 <xsl:when test="$scope='relations'"> | |
| 118 <xsl:apply-templates mode="fiflter-relations"/> | |
| 119 </xsl:when> | |
| 120 </xsl:choose> | |
| 121 </xsl:template> | |
| 122 | |
| 123 <!-- filter-members --> | |
| 124 <xsl:template match="*|text()" mode="filter-members"/> | |
| 125 <xsl:template match="*[@name]" mode="filter-members"> | |
| 126 <xsl:copy> | |
| 127 <xsl:copy-of select="@*" /> | |
| 128 <xsl:attribute name="declaringType"><xsl:value-of select="../@name" /></xsl:attribute> | |
| 129 <xsl:copy-of select="*" /> | |
| 130 </xsl:copy> | |
| 131 </xsl:template> | |
| 132 | |
| 133 <!-- filter-keys --> | |
| 134 <xsl:template match="*|text()" mode="filter-keys"/> | |
| 135 <xsl:template match="m:primaryKey" mode="filter-keys"> | |
| 136 <xsl:apply-templates select="." mode="filter-members"/> | |
| 137 </xsl:template> | |
| 138 | |
| 139 <!-- filter-properties --> | |
| 140 <xsl:template match="*|text()" mode="filter-properties"/> | |
| 141 <xsl:template match="m:property" mode="filter-properties"> | |
| 142 <xsl:apply-templates select="." mode="filter-members"/> | |
| 143 </xsl:template> | |
| 144 | |
| 145 <!-- filter-relations --> | |
| 146 <xsl:template match="*|text()" mode="filter-relations"/> | |
| 147 <xsl:template match="m:hasA | m:hasMany" mode="filter-relations"> | |
| 148 <xsl:apply-templates select="." mode="filter-members"/> | |
| 149 </xsl:template> | |
| 150 | |
| 151 | |
| 152 | |
| 153 <!-- Resolves primaryKey information for the given type name. | |
| 154 @returns m:primaryKey node copy with additional attribute | |
| 155 @declaringType which points to the type where this primaryKey | |
| 156 was defined. | |
| 157 --> | |
| 158 <xsl:template name="getPrimaryKey"> | |
| 159 <xsl:param name="type" /> | |
| 160 <xsl:call-template name="getMembers"> | |
| 161 <xsl:with-param name="type" select="$type"/> | |
| 6 | 162 <xsl:with-param name="scope" select="'keys'"/> |
| 2 | 163 </xsl:call-template> |
| 164 </xsl:template> | |
| 165 | |
| 7 | 166 <!-- expand-member templates are used to process relations |
| 9 | 167 and keys and provide useful information. This mode is designed |
| 8 | 168 to recursively traverse members expanding details like special |
| 169 properties generated by relations. | |
| 170 | |
| 171 expand-member-reference is special mode used to traverse inside | |
| 172 members which are referenced from relations. By default this mode | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
173 creates deep copy of all elements. |
| 8 | 174 |
| 175 Use this templates to produce intermediate model for further | |
| 176 processing by specific code-generators. | |
| 7 | 177 |
| 178 @special - means that the member is a composite part and isn't | |
| 179 accessible directly | |
| 180 --> | |
| 181 | |
| 8 | 182 <xsl:template match="*" mode="expand-member"> |
| 9 | 183 <xsl:copy> |
| 184 <xsl:copy-of select="@*"/> | |
| 185 <xsl:apply-templates mode="expand-member"/> | |
| 186 </xsl:copy> | |
| 8 | 187 </xsl:template> |
| 188 | |
| 189 | |
| 7 | 190 <!-- short form of primaryKey{@name, @type} --> |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
191 <xsl:template match="m:primaryKey[not(m:member)]" mode="expand-member"> |
| 9 | 192 <xsl:variable name="pkName" select="concat(@declaringType, 'Pk')"/> |
| 193 <xsl:variable name="propName" select="@name" /> | |
| 194 | |
| 8 | 195 <xsl:variable name="specialProperty"> |
| 9 | 196 <m:property name="{$propName}" special="true"> |
| 197 <xsl:copy-of select="@*[not(self::name)]" /> | |
| 198 <m:hiddenBy name="{$pkName}" type="{@declaringType}"/> | |
| 7 | 199 <xsl:copy-of select="*" /> |
| 200 </m:property> | |
| 8 | 201 </xsl:variable> |
| 9 | 202 |
| 8 | 203 <xsl:apply-templates select="exsl:node-set($specialProperty)" mode="expand-member"/> |
| 9 | 204 <xsl:copy> |
| 205 <xsl:attribute name="name"><xsl:value-of select="$pkName"/></xsl:attribute> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
206 <xsl:attribute name="declarigType"><xsl:value-of select="@declaringType"/></xsl:attribute> |
| 9 | 207 <m:member name="{@name}" type="{@declaringType}"/> |
| 208 </xsl:copy> | |
| 7 | 209 </xsl:template> |
| 210 | |
| 9 | 211 <!-- long form of primaryKey{ member{@name}+ } --> |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
212 <!-- will be processed using default template --> |
| 7 | 213 |
| 9 | 214 <!-- short form of hasA --> |
| 215 <xsl:template match="m:hasA" mode="expand-member"> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
216 <xsl:variable name="thisPrefix" select="@name"/> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
217 |
| 9 | 218 <xsl:variable name="foreignPk"> |
| 219 <xsl:call-template name="getPrimaryKey"> | |
| 220 <xsl:with-param name="type" select="@type"/> | |
| 221 </xsl:call-template> | |
| 8 | 222 </xsl:variable> |
| 9 | 223 <xsl:variable name="expandedPk"> |
| 224 <xsl:apply-templates select="exsl:node-set($foreignPk)" mode="expand-member"/> | |
| 225 </xsl:variable> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
226 <xsl:variable name="pkMembers"> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
227 <xsl:apply-templates select="exsl:node-set($expandedPk)/*[not(@special)]" mode="resolve-members"/> |
| 9 | 228 </xsl:variable> |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
229 <t:fk> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
230 <xsl:for-each select="exsl:node-set($pkMembers)/*"> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
231 <t:thisKey name="{$thisPrefix}{@name}" matches="{@name}"> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
232 <xsl:copy-of select="."/> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
233 </t:thisKey> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
234 </xsl:for-each> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
235 </t:fk> |
| 7 | 236 </xsl:template> |
| 237 | |
| 9 | 238 <!-- short form of hasA with matched keys specified --> |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
239 <!-- TODO --> |
| 9 | 240 <xsl:template match="m:hasA[m:thisKey]"> |
| 241 <xsl:apply-templates select="m:thisKey" mode="generate-fk-properties"/> | |
| 242 <xsl:copy> | |
| 243 <xsl:copy-of select="@*"/> | |
| 244 <xsl:apply-templates mode="expand-member"/> | |
| 245 </xsl:copy> | |
| 7 | 246 </xsl:template> |
| 247 | |
| 8 | 248 <xsl:template match="m:hasA/m:thisKey" mode="expand-member"> |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
249 <m:member name="{@name}" matches="{@matches}" type="{../@declaringType}"/> |
| 7 | 250 </xsl:template> |
| 251 | |
| 9 | 252 <!-- long form of hasA --> |
| 253 <xsl:template match="m:hasA[m:member]" mode="expand-member"> | |
| 7 | 254 <xsl:apply-templates mode="expand-member"/> |
| 255 </xsl:template> | |
| 256 | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
257 <!-- resolve-members --> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
258 <!-- processes members and copies members to output --> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
259 <!-- TODO: Possible recursion --> |
| 9 | 260 <xsl:template match="m:member" mode="resolve-members"> |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
261 <xsl:variable name="name" select="@name"/> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
262 <xsl:variable name="declaringType" select="@type" /> |
| 9 | 263 <xsl:choose> |
| 264 <xsl:when test="/*[@name=$name and @declaringType=$declaringType]"> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
265 <!-- when reference points to a locally defined member --> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
266 <!-- locally defined members are already expanded --> |
| 9 | 267 <xsl:apply-templates select="/*[@name=$name and @declaringType=$declaringType]" mode="resolve-members"/> |
| 268 </xsl:when> | |
| 269 <xsl:otherwise> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
270 <!-- otherwise try to use getMembers, then expand it and resolve members --> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
271 <xsl:variable name="members"> |
| 9 | 272 <xsl:call-template name="getMembers"> |
| 273 <xsl:with-param name="memberName" select="$name"/> | |
| 274 <xsl:with-param name="type" select="$declaringType"/> | |
| 275 </xsl:call-template> | |
| 276 </xsl:variable> | |
|
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
277 <!-- expand resolved members like 'hasA' and 'thisKey' --> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
278 <xsl:variable name="expanded"> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
279 <xsl:apply-templates select="exsl:node-set($members)" mode="resolve-members"/> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
280 </xsl:variable> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
281 <!-- skip @special members when resolving --> |
|
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
282 <xsl:apply-templates select="exsl:node-set($expanded)/*[not(@special)]" mode="resolve-members"/> |
| 9 | 283 </xsl:otherwise> |
| 284 </xsl:choose> | |
| 285 </xsl:template> | |
| 286 | |
| 287 <xsl:template match="m:property" mode="resolve-members"> | |
| 288 <xsl:copy-of select="."/> | |
| 289 </xsl:template> | |
| 290 | |
| 2 | 291 </xsl:stylesheet> |
