<?xml version="1.0"?>
<!--
 Licensed Materials - Property of IBM

 IBM Cognos Products: fmmd

 (C) Copyright IBM Corp. 2003, 2013

 US Government Users Restricted Rights - Use, duplication or disclosure 
 restricted by GSA ADP Schedule Contract with IBM Corp.
-->
<!-- 
===============================================================================
Model Upgrade 50 to 51 Notes:  

This is an XSLT transformation from a schema version 50 model to a schema 
version 51 model

1:  Remove the limitedLocalScope custom property.


2:  Convert valid hierarchy custom properties to formal properties and remove 
any identified as invalid.  A number of custom properties were copied incorrectly 
from the dimension into the hierarchy and level objects.


3.  Remove calculations and queryItems from the dbQuery and mdQuery querySubjects, and convert them
to queryItem expresssion properties.


4:  Insert the dimension "type", "membersRollup", and "default hierarchy" properties for SAPBW dimensions.


5:  Insert PPDS_CODE into dimension, hierarchy and level objects


6:  Set the value of the custom property hierarchyType for hierarchy objects.


7:  Prefix Baltic collation values with "EN_"

===============================================================================
-->
<xsl:stylesheet xmlns="http://www.developer.cognos.com/schemas/bmt/51/0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fmfunc="http://www.developer.cognos.com/bmt" xmlns:xalan="http://xml.apache.org/xalan" xmlns:table="http://www.developer.cognos.com/schemas/bmt/51/transformTables" exclude-result-prefixes="fmfunc xalan table">
	<xsl:include href="fmmd_generalTemplates.xsl"/>
	<xsl:strip-space elements="*"/> 
	<xsl:output encoding="utf-8" method="xml" indent="no"/>
	<!-- =============================================================================== -->
	<!-- Step 1:  drop the limitedLocalScope custom property.
	-->
	<!-- Template:  Remove limitedLocalScope custom property from the datasource -->
	<xsl:template match="*[local-name() = 'dataSource']/*[local-name()='property' and @*[local-name()='name' and .='limitedLocalScope']]"/>
	<!-- =============================================================================== -->
	<!-- Step 2:  Convert the hierarchy custom properties to formal properties.

		 NOTE:  Custom properties from the querySubject were copied both to the generated dimension and
		 to the generated hierarchy.  Some cleanup is required in both spots where possible.
	-->
	<!-- Template:  Remove the old dimension custom OLAP properties-->
	<xsl:template match="*[local-name()='dimension']/*[local-name()='lastChanged']"/>
	<xsl:template match="*[local-name()='dimension']/*[local-name()='property' and @*[local-name()='name' and (.='uniqueName' or .='dimensionType' or .='hierarchyType' or .='multiRoot' or .='balanced' or .='ragged' or .='sortedHierarchy' or .='hierarchyCardinality' or .='rootMember' or .='defaultHierarchy')]]"/>
	<xsl:template match="*[local-name()='dimension']/*[local-name()='hierarchy']/*[local-name()='property' and @*[local-name()='name' and (.='dimensionType' or .='hierarchyType' or .='uniqueName' or .='multiRoot' or .='balanced' or .='ragged' or .='sortedHierarchy' or .='hierarchyCardinality' or .='rootMember' or .='defaultHierarchy')]]"/>
	<xsl:template match="*[local-name()='dimension']/*[local-name()='hierarchy']/*[local-name()='level']/*[local-name()='property' and @*[local-name()='name' and .='uniqueName']]"/>
	<!-- Template:  Convert 'multiroot', 'balanced', 'ragged', 'sortedHierarchy' custom  properties to actual properties -->
	<xsl:template match="*[local-name()='dimension']/*[local-name()='hierarchy']">
		<xsl:variable name="hierarchy" select="."/>
		<xsl:variable name="externalName" select="*[local-name()='externalName']"/>
		<xsl:element name="{local-name()}">
			<xsl:for-each select="./node()">
				<xsl:choose>
					<!--Remove default hierarchy-->
					<xsl:when test="local-name()='defaultHierarchy' or local-name()='externalName'"/>
					<!-- Remove the old hierarchy custom OLAP properties-->
					<xsl:when test="local-name()='property' and @*[local-name()='name' and (.='dimensionType' or .='multiRoot' or .='balanced' or .='ragged' or .='sortedHierarchy' or .='hierarchyCardinality' or .='rootMember' or .='defaultHierarchy')]"/>
					<xsl:otherwise>
						<xsl:apply-templates select="."/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each>
			<xsl:if test="$externalName">
				<xsl:element name="externalName">
					<xsl:value-of select="$externalName"/>
				</xsl:element>
			</xsl:if>
			<xsl:for-each select="*[local-name()='property' and @*[local-name()='name' and .='multiRoot']]">
				<xsl:element name="{@*[local-name()='name']}">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:for-each>
			<xsl:for-each select="*[local-name()='property' and @*[local-name()='name' and .='balanced']]">
				<xsl:element name="{@*[local-name()='name']}">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:for-each>
			<xsl:for-each select="*[local-name()='property' and @*[local-name()='name' and .='ragged']]">
				<xsl:element name="{@*[local-name()='name']}">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:for-each>
			<xsl:for-each select="*[local-name()='property' and @*[local-name()='name' and .='rootMember']]">
				<xsl:element name="{@*[local-name()='name']}">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:for-each>
			<xsl:element name="sortedHierarchy">none</xsl:element>
			<xsl:for-each select="*[local-name()='property' and @*[local-name()='name' and .='hierarchyCardinality']]">
				<xsl:element name="cardinality">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:for-each>
			<xsl:element name="externalNumberOfLevels">
				<xsl:value-of select="count($hierarchy/*[local-name()='level'])"/>
			</xsl:element>
		</xsl:element>
	</xsl:template>
	<!-- =============================================================================== -->
	<!-- Step 3:  Remove calculations and queryItems from the dbQuery and mdQuery querySubjects, and convert them
	to queryItem expresssion properties.
	-->
	<!-- Template:  Remove <calculations></calculations> from both dbQuery and mdQuery querySubject definitions-->
	<xsl:template match="*[local-name()='querySubject' or local-name()='dimension']/*[local-name()='definition']/*[local-name()='dbQuery' or local-name()='mdQuery']/*[local-name()='calculations']"/>
	<!-- Template:  Remove <queryItems></queryItems> from modelQuery querySubject definitions-->
	<xsl:template match="*[local-name()='querySubject']/*[local-name()='definition']/*[local-name()='modelQuery']/*[local-name()='queryItems']"/>
	<!-- Template:  Transform embedded calculations so that the expression becomes part of the query item definition -->
	<xsl:template match="*[local-name()='queryItem' or local-name()='measure']/*[local-name() = 'columnName']">
		<xsl:variable name="strColumnName" select="string(.)"/>
		<xsl:variable name="querySubject" select="ancestor::*[local-name()='querySubject' or local-name()='dimension'][1]"/>
		<xsl:variable name="querySubject_id" select="generate-id($querySubject)"/>
		<xsl:variable name="qiCalcDefinition" select="key('calcDefinition_using_qsID_columnName', concat($querySubject_id, '||', $strColumnName))"/>
		<xsl:variable name="queryItemsExpr" select="key('queryItems_using_qsID', $querySubject_id)"/>
		<xsl:choose>
			<xsl:when test="$qiCalcDefinition">
				<xsl:element name="expression">
					<xsl:apply-templates select="$qiCalcDefinition/*[local-name()='expression']/node()|$qiCalcDefinition/*[local-name()='refobj']"/>
				</xsl:element>
			</xsl:when>
			<!-- For model queries we rely on the fact that the <queryitems> 
			collector lists the expressions in the order that the queryitems are 
			present under the querysubject this is how the expression is found 
			for a given query item-->
			<!--The attribute names such as 'dataItemName' etc. had to be stripped out 
			of the <refobj> and expression tags-->
			<xsl:when test="$queryItemsExpr">
				<xsl:variable name="qiName" select="string(../*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]])"/>
				<xsl:variable name="queryItemNames" select="key('queryItemNames_using_qsID', $querySubject_id)"/>
				<xsl:for-each select="$queryItemNames">
					<xsl:variable name="pos" select="position()"/>
					<xsl:if test="$qiName = string($queryItemNames[$pos])">
						<xsl:variable name="elemName" select="local-name($queryItemsExpr[$pos])"/>
						<xsl:variable name="expression" select="$queryItemsExpr[$pos]"/>
						<xsl:if test="not($elemName = 'expression')">
							<xsl:element name="expression">
								<xsl:element name="{$elemName}">
									<xsl:for-each select="$expression/node()">
										<xsl:call-template name="copyQIExpression"/>
									</xsl:for-each>
								</xsl:element>
							</xsl:element>
						</xsl:if>
						<xsl:if test="$elemName = 'expression'">
							<xsl:element name="{$elemName}">
								<xsl:for-each select="$expression/node()">
									<xsl:call-template name="copyQIExpression"/>
								</xsl:for-each>
							</xsl:element>
						</xsl:if>
					</xsl:if>
				</xsl:for-each>
			</xsl:when>
			<xsl:otherwise>
				<xsl:element name="externalName">
					<xsl:value-of select="$strColumnName"/>
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<!-- Template:  Insert the dbAggregationRule property for measures -->
	<xsl:template match="*[local-name()='dimension']//*[local-name()='measure']/*[last()]">
		<!-- Copy the anchor element over -->
		<xsl:call-template name="myCopy"/>
		<!-- Insert dbAggregationRule -->
		<xsl:element name="dbAggregationRule">
			<xsl:variable name="bIsMdQuery" select="ancestor::*[local-name()='dimension']/*[local-name()='definition']/*[local-name()='mdQuery']"/>
			<xsl:choose>
				<xsl:when test="$bIsMdQuery and ../*[local-name()='regularAggregate']">
					<xsl:value-of select="../*[local-name()='regularAggregate']"/>
				</xsl:when>
				<xsl:when test="$bIsMdQuery and ../*[local-name()='semiAggregate']">
					<xsl:value-of select="../*[local-name()='semiAggregate']"/>
				</xsl:when>
				<xsl:otherwise>automatic</xsl:otherwise>
			</xsl:choose>
		</xsl:element>
	</xsl:template>
	<!-- Template:  Insert Description -->
	<xsl:template name="copyQIExpression">
		<xsl:choose>
			<xsl:when test="self::text()">
				<xsl:apply-templates select="."/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:element name="{local-name(.)}">
					<xsl:apply-templates select="./node()"/>
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<!-- =============================================================================== -->
	<!-- Step 4:  Insert the dimension "type", "membersRollup", and "default hierarchy" properties for SAPBW dimensions.
	-->
	<!-- Template:  Find the anchor element to append the <type>, <membersRollup>, and <defaultHiearchy> elements -->
	<xsl:template match="*[local-name()='dimension']/*[local-name()='definition' or local-name()='levels' or local-name()='hierarchies' or local-name()='previewFilters' or local-name()='securityFilters' or local-name()='externalizeMethod' or local-name()='externalizeAutoSummary'][last()]">
		<!-- Copy over the element that the template matched against...it's the anchor for inserting the dimension <type> property -->
		<xsl:element name="{local-name()}">
			<xsl:apply-templates select="./*"/>
		</xsl:element>
		<!-- Only add type for dimensions which are based on MD source-->
		<xsl:element name="type">
			<!-- Determine the dimension type -->
			<xsl:variable name="dimType" select="string(../*[local-name()='property' and @*[local-name()='name' and .='dimensionType']])"/>
			<xsl:choose>
				<xsl:when test="($dimType = 'regular') or ($dimType = 'time') or ($dimType = 'currency') or ($dimType = 'measure')">
					<xsl:value-of select="$dimType"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="'regular'"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:element>
		<xsl:element name="membersRollup">true</xsl:element>
		<xsl:if test="../*[local-name()='hierarchy']/*[local-name()='property' and @*[local-name()='name' and .= 'defaultHierarchy'] and .= 'true']">
			<xsl:variable name="hierarchy" select="../*[local-name()='hierarchy']"/>
			<xsl:variable name="ns" select="../ancestor::*[local-name()='namespace'][1]/*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]]"/>
			<xsl:variable name="dimName" select="../*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]]"/>
			<xsl:variable name="hierName" select="$hierarchy/*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]]"/>
			<xsl:element name="defaultHierarchy">
				<xsl:value-of select="concat('[', $ns, '].[', $dimName, '].[', $hierName, ']')"/>
			</xsl:element>
		</xsl:if>
	</xsl:template>
	<!-- =============================================================================== -->
	<!-- Step 5:  Set the PPDS_CODE for SAPBW dimension, hierarchy and level objects.
	-->
	<!-- Template:  Insert the PPDS_CODE for dimensions. -->
	<xsl:template match="*[local-name()='dimension']/*[local-name()='name' or local-name()='description' or local-name()='lastChanged' or local-name()='screenTip'][last()]">
		<xsl:variable name="mdDimension" select="ancestor::*[local-name()='dimension'][1]/*[local-name()='definition']/*[local-name()='mdQuery']/*[local-name()='mdDimension']"/>
		<!-- Copy the anchor element over -->
		<xsl:call-template name="myCopy"/>
		<!-- Insert PPDS_CODE-->
		<xsl:element name="property">
			<xsl:attribute name="name">PPDS_CODE</xsl:attribute>
			<xsl:attribute name="type">hidden</xsl:attribute>
			<xsl:value-of select="concat('2', $mdDimension)"/>
		</xsl:element>
	</xsl:template>
	<!-- Template:  Insert the PPDS_CODE for hierarchy. -->
	<xsl:template match="*[local-name()='dimension']/*[local-name()='hierarchy']/*[local-name()='name' or local-name()='description' or local-name()='lastChanged' or local-name()='screenTip'][last()]">
		<xsl:variable name="uniqueName" select="../*[local-name()='externalName']"/>
		<!-- Copy the anchor element over -->
		<xsl:call-template name="myCopy"/>
		<xsl:call-template name="insertHierarchyType"/>
		<!-- Insert PPDS_CODE-->
		<xsl:element name="property">
			<xsl:attribute name="name">PPDS_CODE</xsl:attribute>
			<xsl:attribute name="type">hidden</xsl:attribute>
			<xsl:value-of select="concat('4', $uniqueName)"/>
		</xsl:element>
	</xsl:template>
	<!-- Template:  Insert the PPDS_CODE for level. -->
	<xsl:template match="*[local-name()='dimension']/*[local-name()='hierarchy']/*[local-name()='level']/*[local-name()='name' or local-name()='description' or local-name()='lastChanged' or local-name()='screenTip' or (local-name()='property' and @*[local-name()='name' and .='dimensionString'])][last()]">
		<xsl:variable name="uniqueName" select="../*[local-name()='externalName']"/>
		<!-- Copy the anchor element over -->
		<xsl:call-template name="myCopy"/>
		<!-- Insert PPDS_CODE-->
		<xsl:element name="property">
			<xsl:attribute name="name">PPDS_CODE</xsl:attribute>
			<xsl:attribute name="type">hidden</xsl:attribute>
			<xsl:value-of select="concat('5', $uniqueName)"/>
		</xsl:element>
	</xsl:template>
	<!-- =============================================================================== -->
	<!-- Step 6:  Set the value of the custom property hierarchyType for hierarchy objects.
	     as follows:

			- default: if the hierarchy is the default, no matter what dimension type is
			- time: if the dimension is a time dimension 
			- text: if the dimension string = "0HIER_NODE" (dimension string is the unique name of the first regular member on level 00) 
			- recursive: if the dimension string = dimension unique name 
			- characteristic otherwise. 
	-->
	<xsl:template name="insertHierarchyType">
		<xsl:variable name="dimension" select="ancestor::*[local-name()='dimension'][1]"/>
		<xsl:variable name="defaultHierarchy">
			<xsl:variable name="strNamespaceName" select="ancestor::*[local-name()='namespace'][1]/*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]]"/>
			<xsl:variable name="strDimensionName" select="$dimension/*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]]"/>
			<xsl:variable name="strHierarchyName" select="../*[local-name()='name' and @*[local-name()='locale' and . = $defaultLocale]]"/>
			<xsl:value-of select="concat('[', $strNamespaceName, '].[', $strDimensionName, '].[', $strHierarchyName, ']')"/>
		</xsl:variable>
		<xsl:variable name="hierarchy" select=".."/>
		<xsl:element name="property">
			<xsl:attribute name="name">hierarchyType</xsl:attribute>
			<xsl:attribute name="type">hidden</xsl:attribute>
			<xsl:variable name="dimensionString" select="concat('[', ../*[local-name()='level'][1]/*[local-name()='property' and @*[local-name()='name' and .='dimensionString']], ']')"/>
			<xsl:variable name="mdDimension" select="string(ancestor::*[local-name()='dimension'][1]/*[local-name()='definition']/*[local-name()='mdQuery']/*[local-name()='mdDimension'])"/>
			<xsl:choose>
				<xsl:when test="$dimension/*[local-name()='property' and @*[local-name()='name' and .='dimensionType'] and .='time']">time</xsl:when>
				<xsl:when test="$hierarchy/*[local-name()='property' and @*[local-name()='name' and .='defaultHierarchy'] and .='true']">default</xsl:when>
				<xsl:when test="$dimensionString = string('[0HIER_NODE]')">text</xsl:when>
				<xsl:when test="$dimensionString = $mdDimension">recursive</xsl:when>
				<xsl:otherwise>characteristic</xsl:otherwise>
			</xsl:choose>
		</xsl:element>
	</xsl:template>
	<!-- =============================================================================== -->
	<!-- Step 7:  Prefix Baltic collation values with "EN_"
	-->
	<xsl:template match="*[local-name()='queryItem']/*[local-name()='collationSequenceName']/text()"> 
		<!-- NOTE:  This is a hash-map mechanism -->
		<xsl:variable name="strBalticValue" select="string(.)"/>
		<!-- context switch -->
		<xsl:for-each select="$collationSequenceTable_root"> 
			<xsl:variable name="lookupValue" select="key('collationSequence_using_balticValue', $strBalticValue)/table:Bering"/> 
			<xsl:choose>
				<xsl:when test="$lookupValue">
					<xsl:value-of select="$lookupValue"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="concat('EN_', $strBalticValue)"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each> 
	</xsl:template> 
	<!-- =============================================================================== -->
	<!-- Global variables:                                                                                                               -->
	<!-- =============================================================================== -->
	<xsl:variable name="sEmptyNamespace" select="string(document('')/*/namespace::*[name()=''])"/>
	<xsl:variable name="nNewSchema" select="number(substring-before(substring-after($sEmptyNamespace, 'http://www.developer.cognos.com/schemas/bmt/'), '/'))"/>
	<xsl:variable name="nOldSchema" select="$nNewSchema - 1"/>
	<table:collationSequenceTable>
		<table:value>
			<table:Baltic>MS_SQL_Latin1_General_CP1_CI_AS</table:Baltic>
			<table:Bering>EN_MS_SQL_Latin1_General_CP1_AS_CI</table:Bering>
		</table:value>
		<table:value>
			<table:Baltic>MS_SQL_Latin1_General_CP1_CS_AS</table:Baltic>
			<table:Bering>EN_MS_SQL_Latin1_General_CP1_AS</table:Bering>
		</table:value>
		<table:value>
			<table:Baltic>TD_ASCII_CS</table:Baltic>
			<table:Bering>EN_TD_ASCII</table:Bering>
		</table:value>
		<table:value>
			<table:Baltic>TD_ASCII_NOT_CS</table:Baltic>
			<table:Bering>EN_TD_ASCII_CI</table:Bering>
		</table:value>
		<table:value>
			<table:Baltic>TD_EBCDIC_CS</table:Baltic>
			<table:Bering>EN_TD_EBCDIC</table:Bering>
		</table:value>
		<table:value>
			<table:Baltic>TD_EBCDIC_NOT_CS</table:Baltic>
			<table:Bering>EN_TD_EBCDIC_CI</table:Bering>
		</table:value>
	</table:collationSequenceTable>
	<xsl:key 
		name="queryItems_using_qsID" 
		match="*[local-name() = 'querySubject']/*[local-name()='definition']/*[local-name()='modelQuery']/*[local-name() = 'queryItems']/*" 
		use="generate-id(ancestor::*[local-name() = 'querySubject'])"/>
	<xsl:key 
		name="calcDefinition_using_qsID_columnName" 
		match="*[local-name() = 'querySubject']/*[local-name() = 'definition']/*[local-name() = 'dbQuery' or local-name() = 'mdQuery']/*[local-name() = 'calculations']/*[local-name() = 'calculationDefinition']" 
		use="concat(generate-id(ancestor::*[local-name() = 'querySubject']), '||', *[local-name()='dataItemName'])"/>
	<xsl:key 
		name="queryItemNames_using_qsID" 
		match="*[local-name() ='queryItem' and ancestor::*[local-name() = 'querySubject']]/*[local-name()='name' and @*[local-name()='locale' and translate(., string('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), string('abcdefghijklmnopqrstuvwxyz')) = translate(/*[local-name()='project']/*[local-name()='defaultLocale'], string('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), string('abcdefghijklmnopqrstuvwxyz'))]]" 
		use="generate-id(ancestor::*[local-name() = 'querySubject'])"/>
	<xsl:key name="collationSequence_using_balticValue" match="table:value" use="table:Baltic"/> 
	<xsl:variable name="collationSequenceTable_root" select="document('')/*/table:collationSequenceTable"/> 
</xsl:stylesheet>