changeset 9:d3542662cf70

working on members preprocessing
author cin
date Sun, 11 Mar 2018 10:27:32 +0300
parents 5fe2e5724331
children 19a8a71eaa54
files data/sample.xml readme.md xslt/model.xsl
diffstat 3 files changed, 79 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/data/sample.xml	Wed Mar 07 15:54:22 2018 +0300
+++ b/data/sample.xml	Sun Mar 11 10:27:32 2018 +0300
@@ -7,7 +7,15 @@
 	<import href="types.xml"/>
 	
 	<entity name="Gallery">
-		<primaryKey name="Id" type="uuid"/>
+		<primaryKey name="GalleryPk">
+			<member name="Id" type="Gallery"/>
+		</primaryKey>
+		
+		<property name="Id" type="uuid" special="true">
+			<hiddenBy name="GalleryPk" type="Gallery"/>
+			<clr:autoGenrated/>
+		</property>
+		
 		<hasMany name="ItemLinks" type="GallertItemLink">
 			<otherKey name="Item"/>
 			<clr:association/>
--- a/readme.md	Wed Mar 07 15:54:22 2018 +0300
+++ b/readme.md	Sun Mar 11 10:27:32 2018 +0300
@@ -71,6 +71,10 @@
 * Ключи - информация для идентификации записей, каждая запись должна иметь по крайней мере первичный ключ.
 * Отношения - информация о связях между сущностями
 
+Ключи рассматриваются являются специальным видом отношений, оны выделены отдельно
+поскольку в генераторе моделей для них предусмотрены специальные механизмы, используемые
+при реализации отношений.
+
 ## Properties
 
 ## PrimaryKey
--- a/xslt/model.xsl	Wed Mar 07 15:54:22 2018 +0300
+++ b/xslt/model.xsl	Sun Mar 11 10:27:32 2018 +0300
@@ -168,7 +168,7 @@
 	</xsl:template>
 	
 	<!-- expand-member templates are used to process relations
-	and keys and provide usefull information. This mode is designed
+	and keys and provide useful information. This mode is designed
 	to recursively traverse members expanding details like special
 	properties generated by relations.
 	
@@ -184,74 +184,95 @@
 	-->
 	
 	<xsl:template match="*" mode="expand-member">
-		<xsl:apply-templates mode="expand-member"/>
+		<xsl:copy>
+			<xsl:copy-of select="@*"/>
+			<xsl:apply-templates mode="expand-member"/>
+		</xsl:copy>
 	</xsl:template>
-	<xsl:template match="text()" mode="expand-member"/>
 	
-	<xsl:template match="*|text()" mode="expand-member-reference"/>
 	
 	<!-- short form of primaryKey{@name, @type} -->
 	<xsl:template match="m:primaryKey" mode="expand-member">
+		<xsl:variable name="pkName" select="concat(@declaringType, 'Pk')"/>
+		<xsl:variable name="propName" select="@name" />
+		
 		<xsl:variable name="specialProperty">
-			<m:property special="true">
-				<xsl:copy-of select="@*" />
-				<m:hiddenBy name="{@name}" type="{@declaringType}"/>
+			<m:property name="{$propName}" special="true">
+				<xsl:copy-of select="@*[not(self::name)]" />
+				<m:hiddenBy name="{$pkName}" type="{@declaringType}"/>
 				<xsl:copy-of select="*" />
 			</m:property>
 		</xsl:variable>
+		
 		<xsl:apply-templates select="exsl:node-set($specialProperty)" mode="expand-member"/>
-		<xsl:apply-templates mode="expand-member"/>
+		<xsl:copy>
+			<xsl:attribute name="name"><xsl:value-of select="$pkName"/></xsl:attribute>
+			<m:member name="{@name}" type="{@declaringType}"/>
+		</xsl:copy>
 	</xsl:template>
 	
-	<!-- long form of primaryKey{ member{@name}+, property{@name, @type} }  -->
-	<xsl:template match="m:primaryKey[m:member | m:property]" mode="expand-member">
+	<!-- long form of primaryKey{ member{@name}+ }  -->
+	<xsl:template match="m:primaryKey[m:member]" mode="expand-member">
 		<xsl:apply-templates mode="expand-member"/>
 	</xsl:template>
 	
-	<!-- properties declared inside relations, they are @special -->
-	<xsl:template match="m:primaryKey/m:property | m:thisKey/m:property" mode="expand-member">
-		<xsl:variable name="specialProperty">
-			<xsl:copy>
-				<xsl:attribute name="special">true</xsl:attribute>
-				<xsl:copy-of select="@*"/>
-				<m:hiddenBy name="{@name}" type="{@declaringType}"/>
-				<xsl:copy-of select="*"/>
-			</xsl:copy>
+	<!-- short form of hasA  -->
+	<xsl:template match="m:hasA" mode="expand-member">
+		<xsl:variable name="foreignPk">
+			<xsl:call-template name="getPrimaryKey">
+				<xsl:with-param name="type" select="@type"/>
+			</xsl:call-template>
 		</xsl:variable>
-		<xsl:apply-templates select="exsl:node-set($specialProperty)" mode="expand-member"/>
+		<xsl:variable name="expandedPk">
+			<xsl:apply-templates select="exsl:node-set($foreignPk)" mode="expand-member"/>
+		</xsl:variable>
+		<xsl:variable name="resolvedPk">
+			<xsl:apply-templates select="exsl:node-set($expandedPk)/m:primaryKey" mode="resolve-members"/>
+		</xsl:variable>
 	</xsl:template>
 	
-	<!-- traverse inside referenced members -->
-	<xsl:template match="m:member" mode="expand-member">
-		<xsl:param name="declaringType"/>
-		<xsl:variable name="expanded">
-			<xsl:call-template name="getMembers">
-				<xsl:with-param name="memberName" select="@name"/>
-				<xsl:with-param name="type" select="$declaringType"/>
-			</xsl:call-template>
-		</xsl:variable>
-		<!-- recusive expand -->
-		<xsl:apply-templates select="exsl:node-set($expanded)" mode="expand-member-reference"/>
+	<!-- short form of hasA with matched keys specified -->
+	<xsl:template match="m:hasA[m:thisKey]">
+		<xsl:apply-templates select="m:thisKey" mode="generate-fk-properties"/>
+		<xsl:copy>
+			<xsl:copy-of select="@*"/>
+			<xsl:apply-templates mode="expand-member"/>
+		</xsl:copy>
 	</xsl:template>
 	
 	<xsl:template match="m:hasA/m:thisKey" mode="expand-member">
-		<xsl:variable name="otherKey">
-			<xsl:call-template name="getPrimaryKey">
-				<xsl:with-param name="type" select="../@type"/>
-			</xsl:call-template>
-		</xsl:variable>
-		<xsl:variable name="otherKeyExpanded">
-			<xsl:apply-templates select="exsl:node-set($otherKey)" mode="expand-member"/>
-		</xsl:variable>
-		<xsl:variable name="pk" select="exsl:node-set($otherKeyExpanded)[1]"/>
-		
-		<m:property name="{@name}" type="{$pk/@type}" hidden="true">
-			<m:related name="{$pk/@name}" type="{../@type}"/>
-		</m:property>
+		<m:member name="{@name}" matches="{@matches}"/>
 	</xsl:template>
 	
-	<xsl:template match="m:thisKey[m:member | property]">
+	<!-- long form of hasA -->
+	<xsl:template match="m:hasA[m:member]" mode="expand-member">
 		<xsl:apply-templates mode="expand-member"/>
 	</xsl:template>
 	
+	<!-- resolve expands -->
+	
+	<xsl:template match="m:member" mode="resolve-members">
+		<xsl:variable name="$name" select="@name"/>
+		<xsl:variable name="$declaringType" select="@declaringType" />
+		
+		<xsl:choose>
+			<xsl:when test="/*[@name=$name and @declaringType=$declaringType]">
+				<xsl:apply-templates select="/*[@name=$name and @declaringType=$declaringType]" mode="resolve-members"/>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:variable name="fragment">
+					<xsl:call-template name="getMembers">
+						<xsl:with-param name="memberName" select="$name"/>
+						<xsl:with-param name="type" select="$declaringType"/>
+					</xsl:call-template>
+				</xsl:variable>
+				<xsl:apply-templates select="exsl:node-set($fragment)/*[not(@special)]" mode="resolve-members"/>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+	
+	<xsl:template match="m:property" mode="resolve-members">
+		<xsl:copy-of select="."/>
+	</xsl:template>
+	
 </xsl:stylesheet>