Added latest version of sysdeftools. See readme.txt for details on content.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/LICENSE.xalan Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,55 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
Binary file sysdeftools/docs/Changes for System Definition v2.0.0.doc has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/docs/readme.txt Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,2 @@
+The specification for the 3.0.0 and System Definition syntaxes can be found at
+http://developer.symbian.org/wiki/index.php/System_Definition
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/filter-module.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ XSLT module which contains the logic to process the filter attribute in the system definition
+-->
+ <xsl:output method="xml" indent="yes"/>
+
+
+<!-- filters can only return hide or show -->
+
+<!-- filter-only = item's @filter can only have items from the list
+ anything with no filters passes
+-->
+<xsl:template match="filter-only" mode="filter"><xsl:param name="item"/>
+ <xsl:if test="$item[@filter]">
+ <xsl:variable name="this" select="."/>
+ <xsl:variable name="my-filters">
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$item/parent::component/@filter"/>
+ </xsl:call-template>
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$item/@filter"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="match">
+ <xsl:for-each select="exslt:node-set($my-filters)/*">
+ <xsl:if test="not($this/*[name()=name(current()) and @v=current()/@v])">x</xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$match!=''">hide</xsl:if>
+ </xsl:if>
+</xsl:template>
+
+
+
+<!-- filter-has = item's @filter must have all filters in the list. ie it can have any other filters, but these must all be present
+-->
+<xsl:template match="filter-has" mode="filter"><xsl:param name="item"/>
+ <xsl:if test="$item[(self::component or self::unit) and not(unit/@filter or self::unit[not(../unit[@filter])])]">
+ <xsl:variable name="my-filters">
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$item/parent::component/@filter"/>
+ </xsl:call-template>
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$item/@filter"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="match">
+ <xsl:for-each select="*">
+ <!-- if(f in this) {return true} else if(!f in this) {return false} else {return !(f is positive)} -->
+ <xsl:choose>
+ <xsl:when test="exslt:node-set($my-filters)/*[name()=name(current()) and @v=current()/@v]"/> <!-- filter in item -->
+ <xsl:when test="exslt:node-set($my-filters)/*[name()!=name(current()) and @v=current()/@v]">x</xsl:when> <!-- !filter in item -->
+ <xsl:when test="self::filter">x</xsl:when> <!-- !(filter is positive) -->
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$match!=''">hide</xsl:if>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="filter-with" mode="filter"><xsl:param name="item"/>
+ <xsl:if test="$item[(self::component or self::unit) and not(unit/@filter or self::unit[not(../unit[@filter])])]">
+ <xsl:variable name="my-filters">
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$item/parent::component/@filter"/>
+ </xsl:call-template>
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$item/@filter"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="match">
+ <xsl:for-each select="*">
+ <xsl:if test="exslt:node-set($my-filters)/*[name()!=name(current()) and @v=current()/@v]">x</xsl:if> <!-- !filter in item -->
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="$match!=''">hide</xsl:if>
+ </xsl:if>
+</xsl:template>
+
+
+
+<xsl:template name="filter-item"> <xsl:param name="f"/>
+ <!-- create an element for a given filter. If the filter's empty make nothing -->
+ <xsl:choose>
+ <xsl:when test="$f=''"/>
+ <xsl:when test="starts-with($f,'!')">
+ <not v="{substring($f,2)}"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <filter v="{$f}"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="filter-list"><xsl:param name="f"/>
+ <!-- turn a filter list into a set of elements (<filter> or <not>) with the attribute "v" containing the "absolute value" of the filter
+ filter="A,B,!C" becomes <filter v="A"/><filter v="B"/><not v="C"/>
+ -->
+ <xsl:choose>
+ <xsl:when test="contains($f,',')">
+ <xsl:call-template name="filter-item"><xsl:with-param name="f" select="normalize-space(substring-before($f,','))"/></xsl:call-template>
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="substring-after($f,',')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="filter-item"><xsl:with-param name="f" select="normalize-space($f)"/></xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/filtering.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,276 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Filter a sysdef in the 2.0 or 3.0 syntax
+-->
+<xsl:output method="xml" indent="yes"/>
+
+<xsl:param name="filter-type">only</xsl:param> <!-- only, has or with -->
+
+<xsl:param name="filter"/> <!-- comma-separated list -->
+
+<xsl:param name="addbuild" select="0"/> <!-- add a system build section that accepts everything -->
+
+
+<xsl:template match="node()|@*"><xsl:copy-of select="."/></xsl:template>
+<xsl:template match="*"><xsl:param name="data"/>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates select="node()">
+ <xsl:with-param name="data" select="$data"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="component|unit"><xsl:param name="data"/> <!-- filterable items -->
+ <xsl:variable name="display">
+ <xsl:apply-templates select="$data" mode="filter">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:if test="$display != 'hide' "> <!-- if hide, remove completely from the output-->
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates select="node()">
+ <xsl:with-param name="data" select="$data"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition">
+ <xsl:variable name="f">
+ <xsl:element name="filter-{$filter-type}">
+ <xsl:call-template name="filter-list">
+ <xsl:with-param name="f" select="$filter"/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="starts-with(@schema,'3.0')"/> <!-- no DTD needed for 3.0 sysdef -->
+ <xsl:when test="$addbuild">
+ <xsl:call-template name="DTD-bld"/> <!-- insert 2.0.1 DTD w/sysbuild parts-->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="DTD"/> <!-- insert 2.0.1 DTD -->
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:variable name="content"> <!-- save content for potential further processing -->
+ <xsl:apply-templates select="node()">
+ <xsl:with-param name="data" select="exslt:node-set($f)/*"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <!-- just output content as is. We could create a template to remove any filtered out items, but so far there's no compelling need -->
+ <xsl:copy-of select="$content"/>
+
+ <xsl:if test="$addbuild">
+ <SystemBuild schema="1.0.0">
+ <configuration name="any" description="text">
+ <xsl:attribute name="filter">
+ <xsl:for-each select="//@filter[not(.=following::*/@filter)]">
+ <xsl:value-of select="."/><xsl:if test="position()!=last()">,</xsl:if>
+ </xsl:for-each>
+ </xsl:attribute>
+ <xsl:for-each select="exslt:node-set($content)/systemModel/layer[descendant::unit]">
+ <!-- only include layers we know have units -->
+ <ref item="{@name}"/>
+ </xsl:for-each>
+ </configuration>
+ </SystemBuild>
+ </xsl:if>
+ </xsl:copy>
+</xsl:template>
+
+
+<xsl:include href="filter-module.xsl"/>
+
+<xsl:template name="DTD-bld">
+<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE SystemDefinition [
+ <!ELEMENT SystemDefinition ( systemModel?, SystemBuild? )>
+ <!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED>
+ <!ELEMENT systemModel (layer+)>
+ <!ELEMENT layer (block* | collection*)*>
+ <!ATTLIST layer
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ levels NMTOKENS #IMPLIED
+ span CDATA #IMPLIED>
+ <!ELEMENT block (subblock* | collection*)*>
+ <!ATTLIST block
+ levels NMTOKENS #IMPLIED
+ span CDATA #IMPLIED
+ level NMTOKEN #IMPLIED
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED>
+ <!ELEMENT subblock (collection)*>
+ <!ATTLIST subblock
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED>
+ <!ELEMENT collection (component)*>
+ <!ATTLIST collection
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ level NMTOKEN #IMPLIED>
+ <!ELEMENT component (unit)*>
+ <!ATTLIST component
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ deprecated CDATA #IMPLIED
+ introduced CDATA #IMPLIED
+ contract CDATA #IMPLIED
+ plugin (Y|N) "N"
+ filter CDATA #IMPLIED
+ class NMTOKENS #IMPLIED
+ supports CDATA #IMPLIED
+ purpose ( optional | mandatory | development ) "optional">
+ <!ELEMENT unit EMPTY>
+ <!ATTLIST unit
+ mrp CDATA #IMPLIED
+ filter CDATA #IMPLIED
+ bldFile CDATA #IMPLIED
+ root CDATA #IMPLIED
+ version NMTOKEN #IMPLIED
+ prebuilt NMTOKEN #IMPLIED
+ late (Y|N) #IMPLIED
+ priority CDATA #IMPLIED>
+ <!ELEMENT SystemBuild (option* | target+ | targetList+ | list+ | configuration+)*>
+ <!ATTLIST SystemBuild schema CDATA #REQUIRED>
+ <!ELEMENT list (ref+)>
+ <!ATTLIST list
+ name ID #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT ref EMPTY>
+ <!ATTLIST ref item CDATA #REQUIRED>
+ <!ELEMENT targetList EMPTY>
+ <!ATTLIST targetList
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ target IDREFS #REQUIRED>
+ <!ELEMENT target EMPTY>
+ <!ATTLIST target
+ name ID #REQUIRED
+ abldTarget CDATA #REQUIRED
+ description CDATA #REQUIRED>
+ <!ELEMENT option EMPTY>
+ <!ATTLIST option
+ name ID #REQUIRED
+ abldOption CDATA #REQUIRED
+ description CDATA #REQUIRED
+ enable (Y | N ) #REQUIRED>
+ <!ELEMENT configuration (listRef+ | ref+ | task+)*>
+ <!ATTLIST configuration
+ name ID #REQUIRED
+ description CDATA #REQUIRED
+ filter CDATA #REQUIRED>
+ <!ELEMENT task (listRef* , (buildLayer | specialInstructions))>
+ <!ELEMENT listRef EMPTY>
+ <!ATTLIST listRef list CDATA #REQUIRED>
+ <!ELEMENT buildLayer EMPTY>
+ <!ATTLIST buildLayer
+ command CDATA #REQUIRED
+ targetList IDREFS #IMPLIED
+ unitParallel (Y | N ) #REQUIRED
+ targetParallel (Y | N ) "N">
+ <!ELEMENT specialInstructions EMPTY>
+ <!ATTLIST specialInstructions
+ name CDATA #REQUIRED
+ cwd CDATA #REQUIRED
+ root CDATA #IMPLIED
+ command CDATA #REQUIRED>
+]>
+]]></xsl:text>
+</xsl:template>
+
+<xsl:template name="DTD">
+<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE SystemDefinition [
+<!ELEMENT SystemDefinition ( systemModel )>
+<!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED
+>
+<!-- all paths are relative to the environment variable specified by the root attribute, or SOURCEROOT if not. -->
+
+<!-- System Model Section of DTD -->
+<!ELEMENT systemModel (layer+)>
+
+<!ELEMENT layer (block* | collection*)*>
+<!-- Kernel Services, Base Services, OS Services, Etc -->
+<!ATTLIST layer
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ levels NMTOKENS #IMPLIED
+ span CDATA #IMPLIED
+>
+
+<!ELEMENT block (subblock* | collection*)*>
+ <!-- Generic OS services, Comms Services, etc -->
+<!ATTLIST block
+ levels NMTOKENS #IMPLIED
+ span CDATA #IMPLIED
+ level NMTOKEN #IMPLIED
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+>
+
+<!ELEMENT subblock (collection)*>
+<!-- Cellular Baseband Services, Networking Services, etc -->
+<!ATTLIST subblock
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+>
+
+<!ELEMENT collection (component)*>
+<!-- Screen Driver, Content Handling, etc -->
+<!ATTLIST collection
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ level NMTOKEN #IMPLIED
+>
+
+<!ELEMENT component (unit)*>
+<!-- contains units or is a package or prebuilt -->
+<!ATTLIST component
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ deprecated CDATA #IMPLIED
+ introduced CDATA #IMPLIED
+ contract CDATA #IMPLIED
+ plugin (Y|N) "N"
+ filter CDATA #IMPLIED
+ class NMTOKENS #IMPLIED
+ supports CDATA #IMPLIED
+ purpose ( optional | mandatory | development ) "optional"
+>
+
+<!ELEMENT unit EMPTY >
+<!-- must be buildable (bld.inf) -->
+<!-- bldFile may someday be removed in favour of mrp -->
+<!ATTLIST unit
+ mrp CDATA #IMPLIED
+ filter CDATA #IMPLIED
+ bldFile CDATA #IMPLIED
+ root CDATA #IMPLIED
+ version NMTOKEN #IMPLIED
+ prebuilt NMTOKEN #IMPLIED
+ late (Y|N) #IMPLIED
+ priority CDATA #IMPLIED
+>
+]>
+]]></xsl:text>
+</xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/group/sysdeftools.mrp Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,7 @@
+component sysdeftools
+
+source \sf\os\buildtools\bldsystemtools\sysdeftools\
+notes_source \component_defs\release.src
+
+
+ipr T
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/joinandparesysdef.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Create a stand-alone sysdef from a linked set of fragments, paring down to just a set of items of the desired rank.
+-->
+ <xsl:output method="xml" indent="yes"/>
+
+ <!-- comma-separated list of IDs in the literal from as the document they appear in (ie same namespace prefix) -->
+<xsl:param name="pare"/>
+
+
+ <!-- the rank item to pare down. This will remove any item of that rank EXCEPT those in $pare -->
+<xsl:param name="rank">package</xsl:param>
+
+<xsl:variable name="pare-list" select="concat(',',translate(normalize-space($pare),' ',','),',')"/> <!-- accept spaces in pare. Pad with commas to make computing easier -->
+
+<xsl:include href="joinsysdef.xsl"/>
+
+<xsl:template match="/SystemDefinition[systemModel]">
+ <xsl:apply-templates select="." mode="join">
+ <xsl:with-param name="filename" select="$path"/>
+ <xsl:with-param name="data" select="current()"/> <!-- just has to be non-empty -->
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="*" mode="filter"> <!-- use this to strip out the unwanted items -->
+ <xsl:param name="item" />
+ <xsl:if test="$rank=name($item) and not(contains($pare-list,concat(',',$item/@id,',')))">hide</xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/joinsysdef-module.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,534 @@
+<?xml version="1.0"?>
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ XSLT module which contains the logic to join a system definition file
+-->
+ <!-- save SF namespace as a constant to avoid the risk of typos-->
+ <xsl:variable name="defaultns">http://www.symbian.org/system-definition</xsl:variable>
+
+<!-- create a stand-alone sysdef from a linked set of fragments -->
+
+<xsl:template match="/*" mode="join">
+ <xsl:message terminate="yes">ERROR: Cannot process this document</xsl:message>
+</xsl:template>
+
+
+<xsl:template match="/SystemDefinition[@schema='3.0.0' and count(*)=1]" mode="join">
+ <xsl:param name="origin" select="/.."/>
+ <xsl:param name="root"/>
+ <xsl:param name="filename"/>
+ <xsl:param name="namespaces"/>
+ <xsl:param name="data" select="/.."/>
+ <xsl:choose>
+ <xsl:when test="$origin"> <!-- this sysdef fragment was linked from a parent sysdef -->
+ <xsl:for-each select="*"> <!-- can be only one -->
+ <xsl:variable name="upid"><xsl:apply-templates select="$origin/@id" mode="my-id"/></xsl:variable> <!-- namespaceless ID of this in parent doc -->
+ <xsl:variable name="id"><xsl:apply-templates select="@id" mode="my-id"/></xsl:variable> <!-- namespaceless ID of this here -->
+ <xsl:variable name="upns"><xsl:apply-templates select="$origin/@id" mode="my-namespace"/></xsl:variable> <!-- ID's namespace in parent doc -->
+ <xsl:variable name="ns"><xsl:apply-templates select="@id" mode="my-namespace"/></xsl:variable> <!-- ID's namespace -->
+ <xsl:if test="$id!=$upid or $ns!=$upns">
+ <xsl:message terminate="yes">ERROR: Linked ID "<xsl:value-of select="$id"/>" (<xsl:value-of select="$ns"/>) must match linking document "<xsl:value-of select="$upid"/>" (<xsl:value-of select="$upns"/>)</xsl:message>
+ </xsl:if>
+ <!-- copy any attributes not already defined (parent doc overrides child doc)-->
+ <xsl:for-each select="@*">
+ <xsl:variable name="n" select="name()"/>
+ <xsl:choose>
+ <xsl:when test="$n='id'"/> <!-- never copy this, always set -->
+ <xsl:when test="$origin/@*[name()=$n]"> <!-- don't copy if already set -->
+ <xsl:message>Cannot set "<xsl:value-of select="$n"/>", already set</xsl:message>
+ </xsl:when>
+ <xsl:when test="$n='before'">
+ <!-- ensure ns is correct (if any future attribtues will ever use an ID, process it here too)-->
+ <xsl:apply-templates select="." mode="join">
+ <xsl:with-param name="namespaces" select="$namespaces"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise><xsl:copy-of select="."/></xsl:otherwise> <!-- just copy anything else -->
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:copy-of select="../namespace::*[not(.=$namespaces)]"/> <!-- set any namespaces not already set (they should all alreayd be, but some XSLT processors are quirky) -->
+ <xsl:apply-templates select="$data" mode="overlay-attributes">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ <xsl:variable name="content">
+ <xsl:apply-templates select="*|comment()" mode="join">
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="filename" select="$filename"/>
+ <xsl:with-param name="data" select="$data"/>
+ <xsl:with-param name="namespaces" select="$namespaces | ../namespace::*[not(.=$namespaces)]"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:apply-templates select="." mode="is-content-filtered"> <!-- optionally add filtered="yes" if some content has been removed -->
+ <xsl:with-param name="content" select="$content"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="$data" mode="overlay-meta">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ <xsl:copy-of select="$content"/>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:when test="function-available('exslt:node-set')"> <!-- this is the root element of a root sysdef -->
+ <!--try to put all namespaces in root element -->
+ <xsl:variable name="nss">
+ <!-- contains node set of namespaces to add to root element.
+ May panic if there are too many single-letter namespaces and this can't create a new one -->
+ <xsl:call-template name="needed-namespaces">
+ <xsl:with-param name="foundns">
+ <xsl:apply-templates select="//*[(self::component or self::collection or self::package or self::layer) and @href]" mode="scan-for-namespaces"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="ns" select="@id-namespace | namespace::* | exslt:node-set($nss)/*"/>
+ <xsl:copy><xsl:copy-of select="@*"/>
+ <xsl:apply-templates select="self::*[not(@id-namespace)]" mode="add-id-ns"/>
+ <xsl:for-each select="exslt:node-set($nss)/*"> <!-- add namespace definitions -->
+ <xsl:attribute name="xmlns:{name()}">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:for-each>
+ <!-- no need to call is-content-filtered, it never will be from this element -->
+ <xsl:apply-templates select="*|comment()" mode="join">
+ <xsl:with-param name="namespaces" select="$ns"/>
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="data" select="$data"/>
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise> <!-- can't handle node-set() so put the namespaces in the document instead of the root element-->
+ <xsl:variable name="ns" select="@id-namespace | namespace::*"/>
+ <xsl:copy><xsl:copy-of select="@*"/>
+ <!-- no need to call is-content-filtered, it never will be from this element -->
+ <xsl:apply-templates select="*|comment()" mode="join">
+ <xsl:with-param name="namespaces" select="$ns"/>
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="data" select="$data"/>
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*" mode="scan-for-namespaces"/> <!-- just in case of errors, consider replacing by terminate -->
+<xsl:template match="*[@href and not(self::meta)]" mode="scan-for-namespaces">
+ <!-- produce a list of namespace-prefix namespace pairs separated by newlines, in reverse order found in documents
+ reverse order so we can try to use the first namespace prefix defined if it's available-->
+ <xsl:for-each select="document(@href,.)/*">
+ <xsl:apply-templates select="//*[(self::component or self::collection or self::package or self::layer) and @href]" mode="scan-for-namespaces"/>
+ <xsl:for-each select="//namespace::* | @id-namespace">
+ <xsl:value-of select="concat(name(),' ',.,'
')"/>
+ </xsl:for-each>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="needed-namespaces">
+ <xsl:param name="foundns"/>
+ <xsl:param name="usedpre"/>
+
+ <xsl:if test="$foundns!=''">
+ <xsl:variable name="line" select="substring-before($foundns,'
')"/> <!-- always has trailing newline -->
+ <xsl:variable name="name" select="substring-after($line,' ')"/> <!-- namespace prefix -->
+ <xsl:variable name="remainder" select="substring-after($foundns,'
')"/>
+ <xsl:variable name="newprefix">
+ <xsl:if test="not(contains(concat('
',$remainder),concat('
',$line,'
'))) and
+ not(//namespace::*[.=$name] or @id-namespace[.=$name] or (not(@id-namespace) and $defaultns=$name))">
+ <xsl:apply-templates select="." mode="ns-prefix">
+ <xsl:with-param name="ns" select="$name"/>
+ <xsl:with-param name="pre" select="substring-before($line,' ')"/>
+ <xsl:with-param name="dontuse" select="$usedpre"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:if test="$newprefix!=''">
+ <!-- can treat this as if it were a namespace node -->
+ <xsl:element name="{$newprefix}">
+ <xsl:value-of select="$name"/>
+ </xsl:element>
+ </xsl:if>
+ <xsl:if test="$remainder!=''">
+ <xsl:call-template name="needed-namespaces">
+ <xsl:with-param name="foundns" select="$remainder"/>
+ <xsl:with-param name="usedpre" select="concat($usedpre,' ',$newprefix,' ')"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition" mode="ns-prefix">
+ <!-- should be able to replace this with mechanism that uses the XSLT processor's own ability to generate namespaces -->
+ <xsl:param name="ns"/>
+ <xsl:param name="pre"/>
+ <xsl:param name="dontuse"/>
+ <xsl:param name="chars">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</xsl:param>
+ <xsl:variable name="name" select="substring(substring-after($ns,'http://www.'),1,1)"/>
+ <xsl:choose>
+ <xsl:when test="$pre!='' and $pre!='id-namespace' and not(//namespace::*[name()=$pre]) and not(contains($dontuse,concat(' ',$pre,' ')))">
+ <xsl:value-of select="$pre"/>
+ </xsl:when>
+ <xsl:when test="$ns='' and $chars=''">
+ <xsl:message terminate="yes">ERROR: Cannot create namespace prefix for downstream default namespace in <xsl:value-of select="*/@id"/></xsl:message>
+ </xsl:when>
+ <xsl:when test="$name!='' and not(contains($dontuse,concat(' ',$name,' ')))"><xsl:value-of select="$name"/></xsl:when>
+ <xsl:when test="namespace::*[name()=substring($chars,1,1)] or contains($dontuse,concat(' ',substring($chars,1,1),' '))">
+ <xsl:apply-templates mode="ns-prefix">
+ <xsl:with-param name="chars" select="substring($chars,2)"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring($chars,1,1)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="unit" mode="join"> <xsl:param name="root"/><xsl:param name="filename"/><xsl:param name="data"/>
+ <xsl:variable name="display">
+ <xsl:apply-templates select="$data" mode="filter">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:if test="$display != 'hide' "> <!-- if hide, remove completely from the output-->
+ <xsl:element name="{name()}">
+ <xsl:apply-templates select="@*" mode="join">
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+ </xsl:element>
+ </xsl:if>
+</xsl:template>
+
+<!-- override mode="meta" to translate metadata sections. By default, include -->
+<xsl:template match="meta" priority="2" mode="join"><xsl:param name="data"/>
+ <xsl:variable name="display">
+ <xsl:apply-templates select="$data" mode="filter">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:if test="$display != 'hide' "> <!-- if hide, remove completely from the output-->
+ <xsl:apply-templates select="." mode="meta">
+ <xsl:with-param name="display" select="$display"/>
+ <xsl:with-param name="data" select="$data"/>
+ </xsl:apply-templates>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="meta[@rel='link-mapping']" priority="3" mode="join"/> <!--these are only used in the joining process, so remove from output -->
+
+
+<xsl:template match="*" mode="join">
+ <xsl:param name="root"/><xsl:param name="filename"/><xsl:param name="namespaces"/><xsl:param name="data"/>
+ <!-- get attribtues from overlay -->
+ <!-- test for presence, if filtered out, just return -->
+ <!-- test for children, if it has some, but they're filtered out, either return or leave as empty, dependening on filter rule
+ if had items and now has none, options:
+ still has meta: keep / delete
+ still has comments: keep / delete
+ -->
+ <xsl:variable name="display">
+ <xsl:apply-templates select="$data" mode="filter">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:if test="$display != 'hide' "> <!-- if hide, remove completely from the output-->
+ <xsl:variable name="href">
+ <xsl:apply-templates select="." mode="link">
+ <xsl:with-param name="data" select="$data"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+
+ <xsl:element name="{name()}"> <!-- use this instead of <copy> so xalan doesn't add extra wrong namespaces -->
+ <xsl:apply-templates select="@*" mode="join">
+ <xsl:with-param name="namespaces" select="$namespaces"/>
+ </xsl:apply-templates>
+ <xsl:if test="$display != '' ">
+ <!-- custom attribute to indicate how this is to be represented. Blank indicates normal, hide removes from the output (see above), anything else is put in the attribute -->
+ <xsl:attribute name="display"><xsl:value-of select="$display"/></xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates select="$data" mode="overlay-attributes">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ <xsl:choose>
+ <xsl:when test="$href !='' ">
+ <xsl:variable name="prefixmap" select="ancestor::SystemDefinition/*/meta[@rel='link-mapping']/map-prefix[starts-with($href,@link)]"/>
+ <xsl:variable name="origin" select="."/>
+ <xsl:apply-templates select="document($href,.)/*" mode="join">
+ <xsl:with-param name="origin" select="$origin"/>
+ <xsl:with-param name="data" select="$data"/>
+ <xsl:with-param name="namespaces" select="$namespaces"/>
+ <xsl:with-param name="filename">
+ <xsl:call-template name="joinpath">
+ <xsl:with-param name="file" select="$filename"/>
+ <xsl:with-param name="rel">
+ <xsl:choose>
+ <xsl:when test="$prefixmap">
+ <xsl:value-of select="$prefixmap/@to"/>
+ <xsl:value-of select="substring-after($href,$prefixmap/@link)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$href"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name="root">
+ <xsl:value-of select="$root"/>/<xsl:call-template name="lastbefore">
+ <xsl:with-param name="string" select="$href"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="content">
+ <xsl:apply-templates select="*|comment()" mode="join">
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="filename" select="$filename"/>
+ <xsl:with-param name="namespaces" select="$namespaces"/>
+ <xsl:with-param name="data" select="$data"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:apply-templates select="." mode="is-content-filtered"> <!-- add filtered="yes" if some content has been removed -->
+ <xsl:with-param name="content" select="$content"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="$data" mode="overlay-meta">
+ <xsl:with-param name="item" select="current()"/>
+ </xsl:apply-templates>
+ <xsl:copy-of select="$content"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:element>
+ </xsl:if>
+</xsl:template>
+
+<!-- By default, do nothing. Can override template to add filtered="yes" if need to track what's a placeholder and what's been filtered
+ implement with param name="content"
+-->
+<xsl:template mode="is-content-filtered" match="*" priority="-2"/>
+
+
+<xsl:template match="@mrp[starts-with(.,'/')] | @bldFile[starts-with(.,'/')] | @base[starts-with(.,'/')]" mode="join">
+ <xsl:copy-of select="."/>
+</xsl:template>
+
+
+<xsl:template match="@mrp|@bldFile|@base" mode="join"> <xsl:param name="root"/><xsl:param name="filename"/>
+ <xsl:attribute name="{name()}">
+ <xsl:call-template name="joinpath">
+ <xsl:with-param name="file" select="$filename"/>
+ <xsl:with-param name="rel" select="."/>
+ </xsl:call-template>
+ </xsl:attribute>
+</xsl:template>
+
+
+<xsl:template match="@href" mode="join"/> <!--never copy this into the generated doc, that's the whole point of this module -->
+
+<xsl:template match="@*" mode="my-namespace"> <!-- the namespace of an ID -->
+ <xsl:choose>
+ <xsl:when test="contains(.,':')">
+ <xsl:value-of select="ancestor::*/namespace::*[name()=substring-before(current(),':')]"/>
+ </xsl:when>
+ <xsl:when test="/SystemDefinition/@id-namespace">
+ <xsl:value-of select="/SystemDefinition/@id-namespace"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$defaultns"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="@*" mode="my-id"> <!-- the ID with namespace prefix removed -->
+ <xsl:choose>
+ <xsl:when test="contains(.,':')">
+ <xsl:value-of select="substring-after(.,':')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="*" mode="err-path">
+<xsl:if test="../@id">
+ <xsl:apply-templates select=".." mode="err-path"/>/</xsl:if>
+<xsl:value-of select="@id"/>
+</xsl:template>
+
+
+<xsl:template match="@id|@before" mode="join">
+ <xsl:param name="namespaces"/>
+ <!-- this will change the namespace prefixes for all IDs to match the root document -->
+ <xsl:variable name="ns">
+ <xsl:apply-templates select="." mode="my-namespace"/>
+ </xsl:variable>
+ <xsl:if test="$ns=''">
+ <xsl:message terminate="yes">ERROR: Could not find namespace for <xsl:value-of select="name()"/> "<xsl:value-of select="."/>" in <xsl:apply-templates select="../.." mode="err-path"/>
+ <xsl:text>
</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:variable name="prefix" select="name($namespaces[.=$ns])"/>
+ <xsl:attribute name="{name()}">
+ <xsl:choose>
+ <xsl:when test="$prefix = 'id-namespace' or (not($namespaces[name()='id-prefix']) and $ns=$defaultns)"/> <!-- it's the default namespace, no prefix -->
+ <xsl:when test="$prefix='' and contains(.,':')">
+ <!-- complex: copy id and copy namespace (namespace should be copied already)-->
+ <xsl:value-of select="."/>
+ </xsl:when>
+ <xsl:when test="$prefix='' and $ns=$defaultns"/> <!-- no prefix and it's the default -->
+ <xsl:when test="$prefix!=''"> <!-- just change the prefix -->
+ <xsl:value-of select="concat($prefix,':')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message terminate="yes">ERROR: Joining error in resolving namespace for <xsl:value-of select="name()"/> "<xsl:value-of select="."/>" in <xsl:apply-templates select="../.." mode="err-path"/>
+ <xsl:text>
</xsl:text></xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="." mode="my-id"/>
+ </xsl:attribute>
+</xsl:template>
+
+
+
+<xsl:template match="@*|comment()" mode="join"><xsl:copy-of select="."/></xsl:template>
+
+
+<!-- path handling follows -->
+
+ <xsl:template name="lastbefore"><xsl:param name="string"/><xsl:param name="substr" select="'/'"/>
+ <xsl:if test="contains($string,$substr)">
+ <xsl:value-of select="substring-before($string,$substr)"/>
+ <xsl:if test="contains(substring-after($string,$substr),$substr)">
+ <xsl:value-of select="$substr"/>
+ </xsl:if>
+ <xsl:call-template name="lastbefore">
+ <xsl:with-param name="string" select="substring-after($string,$substr)"/>
+ <xsl:with-param name="substr" select="$substr"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+ <xsl:template name="joinpath"><xsl:param name="file"/><xsl:param name="rel"/>
+ <xsl:choose>
+ <xsl:when test="(contains($rel,'://') and not(contains(substring-before($rel,'://'),'/'))) or starts-with($rel,'/')"> <!-- absolute URI or absolute path-->
+ <xsl:value-of select="$rel"/>
+ </xsl:when>
+ <xsl:otherwise> <!-- relative link -->
+ <xsl:call-template name="reducepath">
+ <xsl:with-param name="file">
+ <xsl:call-template name="lastbefore">
+ <xsl:with-param name="string" select="$file"/>
+ </xsl:call-template>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select="$rel"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+<xsl:template name="reducepath"><xsl:param name="file"/>
+ <xsl:call-template name="reducedotdotpath">
+ <xsl:with-param name="file">
+ <xsl:call-template name="reducedotpath">
+ <xsl:with-param name="file" select="$file"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="reducedotdotpath"><xsl:param name="file"/>
+ <xsl:choose>
+ <xsl:when test="starts-with($file,'../')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="reducedotdotpath">
+ <xsl:with-param name="file" select="substring($file,4)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($file,'/../')">
+ <xsl:call-template name="reducepath">
+ <xsl:with-param name="file">
+ <xsl:call-template name="lastbefore">
+ <xsl:with-param name="string" select="substring-before($file,'/../')"/>
+ </xsl:call-template>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select="substring-after($file,'/../')"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$file"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+<xsl:template name="reducedotpath"><xsl:param name="file"/>
+ <xsl:choose>
+ <xsl:when test="starts-with($file,'./')">
+ <xsl:call-template name="reducedotpath">
+ <xsl:with-param name="file" select="substring($file,3)"/>
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:when test="contains($file,'/./')">
+ <xsl:call-template name="reducepath">
+ <xsl:with-param name="file">
+ <xsl:value-of select="substring-before($file,'/./')"/>
+ <xsl:text>/</xsl:text>
+ <xsl:value-of select="substring-after($file,'/./')"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="substring($file,string-length($file) - 1) = '/.'">
+ <xsl:value-of select="substring($file,1,string-length($file) - 2)"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$file"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+<!-- overridable templates follow -->
+
+
+<xsl:template match="*" mode="filter" priority="-9"/> <!-- by default show -->
+<xsl:template match="*" mode="overlay-attributes" priority="-9"/> <!-- by default do nothing -->
+<xsl:template match="*" mode="overlay-meta" priority="-9"/> <!-- by default do nothing -->
+<xsl:template match="/SystemDefinition" mode="add-id-ns" priority="-9"/> <!-- some tools may have an easier job if this were always present, but, by default, assume it can just stay implied -->
+
+<xsl:template match="*" mode="link" priority="-1"> <!-- can be overriden to allow custom changes to href values -->
+<xsl:value-of select="@href"/>
+</xsl:template>
+
+
+<xsl:template match="*" mode="meta" priority="-9"><xsl:param name="data"/><xsl:param name="display"/>
+ <xsl:element name="{name()}">
+ <xsl:copy-of select="@*[name()!='href']"/> <!-- copy all attributes as is, always drop href -->
+ <xsl:choose>
+ <xsl:when test="$display='local' and @href and contains(@href,':') and not(starts-with(@href,'file:'))">
+ <!-- non-local URL: only want local URLs, so keep href as is-->
+ <xsl:copy-of select="@href"/>
+ </xsl:when>
+ <xsl:when test="@href">
+ <xsl:copy-of select="document(@href,.)/*"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="*|comment()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:element>
+</xsl:template>
+
+
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/joinsysdef.pl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,748 @@
+# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!/usr/bin/perl
+
+use strict;
+
+
+use FindBin; # for FindBin::Bin
+use lib $FindBin::Bin;
+use lib "$FindBin::Bin/lib";
+
+use Cwd;
+use Cwd 'abs_path';
+use Getopt::Long;
+use File::Basename;
+use File::Spec;
+use XML::DOM;
+
+my $output;
+my $path;
+my $config;
+my @includes;
+my %defineParams;
+my %defines;
+my $defaultns = 'http://www.symbian.org/system-definition'; # needed if no DTD
+
+my @newarg;
+foreach my $a (@ARGV)
+ { #extract all -I parameters from the parameter list
+ if($a=~s/^-I//)
+ {
+ push(@includes,$a);
+ }
+ else
+ {
+ push(@newarg,$a);
+ }
+ }
+@ARGV=@newarg;
+
+# need to add options for controlling which metas are filtered out and which are included inline
+GetOptions
+ (
+ 'path=s' => \$path,
+ 'output=s' => \$output,
+ 'config=s' => \$config
+ );
+
+# -path specifies the full system-model path to the file which is being processed.
+# This must be an absolute path if you're processing a root sysdef.
+# If processing a pkgdef file, you can use "./package_definition.xml" to leave all links relative. Though I can't really see the use case for this.
+
+# -output specifies the file to save the output to. If not specified this will write to stdout
+
+# -config specifies the name of an .hrh file in which the configuration data is acquired from. If not set, no confguration will be done.
+
+# -I[path] specifies the include paths to use when resolving #includes in the .hrh file. Same syntax as cpp command uses. Any number of these can be provided.
+
+
+# if config is not set, no confguration will be done.
+# If it is set, all configuration metadata will be processed and stripped from the output, even if the confguration data is empty
+
+ if($path eq '') {$path = '/os/deviceplatformrelease/foundation_system/system_model/system_definition.xml'}
+
+
+my $sysdef = &abspath(shift); # resolve the location of the root sysdef
+
+
+
+# rootmap is a mapping from the filesystem to the paths in the doc
+my %rootmap = &rootMap($path,$sysdef);
+my %nsmap;
+my %urimap;
+
+if($config ne '')
+ { # run cpp to get all #defines
+ &getDefines($config);
+ }
+
+my $parser = new XML::DOM::Parser;
+my $sysdefdoc = $parser->parsefile ($sysdef);
+
+
+# find all the namespaces used in all trhe fragments and use that
+# to set the namespaces ni the root element of the created doc
+# should be able to optimise by only parsing each doc once and
+# maybe skipping the contends of <meta>
+my @nslist = &namespaces($sysdef,$sysdefdoc->getDocumentElement());
+
+
+while(@nslist)
+ {
+ my $uri = shift(@nslist);
+ my $prefix =shift(@nslist);
+ if($prefix eq 'id namespace'){$prefix=''}
+ if(defined $urimap{$uri}) {next} # already done this uri
+ $urimap{$uri} = $prefix;
+ if($nsmap{$prefix})
+ { # need a new prefix for this, guess from the URI (for readability)
+ if($uri=~/http:\/\/(www\.)?([^.\/]+)\./) {$prefix = $2}
+ my $i=0;
+ while($nsmap{$prefix})
+ { # still no prefix, just make up
+ $prefix="ns$i";
+ $i++;
+ # next line not really necessary, but it's a good safety to stop infinite loops
+ $i eq 1000 && die "cannot create namespace prefix for $uri";
+ }
+ }
+ $nsmap{$prefix}=$uri;
+ }
+
+my $docroot = $sysdefdoc->getDocumentElement;
+
+my $ns = $docroot->getAttribute('id-namespace');
+if(!$ns && $nsmap{''})
+ {
+ $docroot->setAttribute('id-namespace',$nsmap{''});
+ }
+while(my($pre,$uri) = each(%nsmap))
+ {
+ $pre ne '' || next ;
+ $docroot->setAttribute("xmlns:$pre",$uri);
+ }
+
+&walk($sysdef,$docroot); # process the XML
+
+
+# print to file or stdout
+if($output eq '')
+ {
+ print $sysdefdoc->toString;
+ }
+else
+ {
+ $sysdefdoc->printToFile($output);
+ }
+
+
+sub abspath
+ { # normalize the path into an absolute one
+ my ($name,$path) = fileparse($_[0]);
+ $path=~tr,\\,/,;
+ if( -e $path)
+ {
+ return abs_path($path)."/$name";
+ }
+ my @dir = split('/',$_[0]);
+ my @new;
+ foreach my $d (@dir)
+ {
+ if($d eq '.') {next}
+ if($d eq '..')
+ {
+ pop(@new);
+ next;
+ }
+ push(@new,$d)
+ }
+ return join('/',@new);
+ }
+
+sub rootMap {
+ my @pathdirs = split(/\//,$_[0]);
+ my @rootdirs = split(/\//,$_[1]);
+
+ while(lc($rootdirs[$#rootdirs]) eq lc($pathdirs[$#pathdirs]) )
+ {
+ pop(@rootdirs);
+ pop(@pathdirs);
+ }
+ return (join('/',@rootdirs) => join('/',@pathdirs) );
+ }
+
+sub rootMapMeta {
+ # find all the explict path mapping from the link-mapping metadata
+ my $node = shift;
+ foreach my $child (@{$node->getChildNodes})
+ {
+ if ($child->getNodeType==1 && $child->getTagName eq 'map-prefix')
+ {
+ my $from = $child->getAttribute('link');
+ my $to = $child->getAttribute('to'); # optional, but blank if not set
+ $rootmap{$from} = $to;
+ }
+ }
+ # once this is processed we have no more need for it. Remove from output
+ $node->getParentNode->removeChild($node);
+ }
+
+
+sub walk
+ { # walk through the doc, resolving all links
+ my $file = shift;
+ my $node = shift;
+ my $type = $node->getNodeType;
+ if($type!=1) {return}
+ my $tag = $node->getTagName;
+ if($tag=~/^(layer|package|collection|component)$/ )
+ {
+ if($file eq $sysdef)
+ {
+ &fixIDs($node); # normalise all IDs in the root doc. Child docs are handled elsewhere.
+ }
+ my $link= $node->getAttribute('href');
+ if($link)
+ {
+ my $file = &resolvePath($file,$link);
+ if(-e $file)
+ {
+ &combineLink($node,&resolveURI($file,$link));
+ }
+ else
+ {
+ print STDERR "Note: $file not found\n";
+ }
+ return;
+ }
+ }
+ elsif($tag=~/^(SystemDefinition|systemModel)$/ )
+ {
+ }
+ elsif($tag eq 'unit')
+ {
+ foreach my $atr ('bldFile','mrp','base','proFile')
+ {
+ my $link= $node->getAttribute($atr);
+ if($link && !($link=~/^\//))
+ {
+ $link= &abspath(File::Basename::dirname($file)."/$link");
+ foreach my $a (keys %rootmap) {
+ $link=~s,^$a,$rootmap{$a},ie;
+ }
+ # remove leading ./ which is used to indicate that paths should remain relative
+ $link=~s,^\./([^/]),$1,;
+ $node->setAttribute($atr,$link);
+ }
+ }
+ }
+ elsif($tag eq 'meta')
+ {
+ my $link= $node->getAttribute('href');
+ $link=~s,^file://(/([a-z]:/))?,$2,; # convert file URI to absolute path
+ if ($link ne '' )
+ {
+ if($link=~/^[\/]+:/)
+ {
+ print STDERR "Note: Remote URL $link not embedded\n";
+ next; # do not alter children
+ }
+ if(! ($link=~/^\//))
+ {
+ $link= &abspath(File::Basename::dirname($file)."/$link");
+ }
+ if(! -e $link)
+ {
+ print STDERR "Warning: Local metadata file not found: $link\n";
+ next; # do not alter children
+ }
+ # if we're here we can just embed the file
+ # no processing logic is done! It's just embedded blindly
+ my $metadoc = $parser->parsefile ($file);
+ my $item =&firstElement($metadoc->getDocumentElement);
+ if(!$item)
+ {
+ print STDERR "Warning: Could not process metadata file: $link\n";
+ next; # do not alter children
+ }
+ $node->removeAttribute('href');
+ foreach my $child (@{$item->getChildNodes})
+ {
+ &blindCopyInto($node,$child);
+ next;
+ }
+ }
+ if($node->getAttribute('rel') eq 'link-mapping')
+ {# need to process this now
+ &rootMapMeta($node);
+ }
+ return;
+ }
+ else {return}
+ my $checkversion=0;
+ foreach my $item (@{$node->getChildNodes})
+ {
+ #print $item->getNodeType,"\n";
+ &walk($file,$item);
+ $checkversion = $checkversion || ($tag eq 'component' && $item->getNodeType==1 && $item->getAttribute('version') ne '');
+ }
+
+ if($checkversion && $config ne '')
+ { # need to check the conf metadata on the units in this component
+ &doCmpConfig($node);
+ }
+ foreach my $item (@{$node->getChildNodes})
+ {
+ if ($item->getNodeType==1 && $item->getTagName eq 'meta')
+ {
+ &processMeta($item);
+ }
+ }
+ }
+
+
+sub combineLink
+ {
+ # combine data from linked sysdef fragment w/ equivalent element in parent document
+ my $node = shift;
+ my $file = shift;
+ my $getfromfile = &localfile($file);
+ $getfromfile eq '' && return; # already raised warning, no need to repeat
+ my $doc = $parser->parsefile ($getfromfile);
+ my $item =&firstElement($doc->getDocumentElement);
+ $item || die "badly formatted $file";
+ &fixIDs($item);
+ my %up = &atts($node);
+ my %down = &atts($item);
+ $up{'id'} eq $down{'id'} || die "$up{id} differs from $down{id}";
+ $node->removeAttribute('href');
+ foreach my $v (keys %up) {delete $down{$v}}
+ foreach my $v (keys %down)
+ {
+ $node->setAttribute($v,$down{$v})
+ }
+ foreach my $child (@{$item->getChildNodes})
+ {
+ ©Into($node,$child);
+ }
+ &walk($file,$node);
+ }
+
+
+sub blindCopyInto
+ {
+ # make a deep copy the node (2nd arg) into the element (1st arg)
+ my $parent=shift;
+ my $item = shift;
+ my $doc = $parent->getOwnerDocument;
+ my $type = $item->getNodeType;
+ my $new;
+ if($type==1)
+ {
+ $new = $doc->createElement($item->getTagName);
+ my %down = &atts($item);
+ while(my($a,$b) = each(%down))
+ {
+ $new->setAttribute($a,$b);
+ }
+ foreach my $child (@{$item->getChildNodes})
+ {
+ &blindCopyInto($new,$child);
+ }
+ }
+ elsif($type==3)
+ {
+ $new = $doc->createTextNode ($item->getData);
+ }
+ elsif($type==8)
+ {
+ $new = $doc->createComment ($item->getData);
+ }
+ if($new)
+ {
+ $parent->appendChild($new);
+ }
+ }
+
+sub copyInto
+ {
+ # make a deep copy the node (2nd arg) into the element (1st arg)
+ my $parent=shift;
+ my $item = shift;
+ my $doc = $parent->getOwnerDocument;
+ my $type = $item->getNodeType;
+ my $new;
+ if($type==1)
+ {
+ &fixIDs($item);
+ $new = $doc->createElement($item->getTagName);
+ my %down = &atts($item);
+ foreach my $ordered ('id','name','bldFile','mrp','level','levels','introduced','deprecated','filter')
+ {
+ if($down{$ordered})
+ {
+ $new->setAttribute($ordered,$down{$ordered});
+ delete $down{$ordered}
+ }
+ }
+ while(my($a,$b) = each(%down))
+ {
+ $new->setAttribute($a,$b);
+ }
+ foreach my $child (@{$item->getChildNodes})
+ {
+ ©Into($new,$child);
+ }
+ }
+ elsif($type==3)
+ {
+ $new = $doc->createTextNode ($item->getData);
+ }
+ elsif($type==8)
+ {
+ $new = $doc->createComment ($item->getData);
+ }
+ if($new)
+ {
+ $parent->appendChild($new);
+ }
+ }
+
+sub getNs
+ {
+ # find the namespace URI that applies to the specified prefix.
+ my $node = shift;
+ my $pre = shift;
+ my $uri = $node->getAttribute("xmlns:$pre");
+ if($uri) {return $uri}
+ my $parent = $node->getParentNode;
+ if($parent && $parent->getNodeType==1)
+ {
+ return getNs($parent,$pre);
+ }
+ }
+
+
+sub fixIDs
+ {
+ # translate the ID to use the root doc's namespaces
+ my $node = shift;
+ foreach my $id ('id','before')
+ {
+ &fixID($node,$id);
+ }
+}
+
+sub fixID
+ {
+ # translate the ID to use the root doc's namespaces
+ my $node = shift;
+ my $attr = shift || 'id';
+ my $id = $node->getAttribute($attr);
+ if($id eq '') {return}
+ my $ns;
+ if($id=~s/^(.*)://)
+ { # it's got a ns, find out what it is
+ my $pre = $1;
+ $ns=&getNs($node,$pre);
+ }
+ else
+ {
+ $ns = $node->getOwnerDocument->getDocumentElement->getAttribute("id-namespace") ||
+ $defaultns;
+ }
+ $ns = $urimap{$ns};
+ $id = ($ns eq '') ? $id : "$ns:$id";
+ return $node->setAttribute($attr,$id);
+}
+
+sub firstElement {
+ # return the first element in this node
+ my $node = shift;
+ foreach my $item (@{$node->getChildNodes}) {
+ if($item->getNodeType==1) {return $item}
+ }
+}
+
+
+sub atts {
+ # return a hash of all attribtues defined for this element
+ my $node = shift;
+ my %at = $node->getAttributes;
+ my %list;
+ foreach my $a (keys %{$node->getAttributes})
+ {
+ if($a ne '')
+ {
+ $list{$a} = $node->getAttribute ($a);
+ }
+ }
+ return %list;
+}
+
+
+sub ns
+ {
+ # return a hash of ns prefix and uri -- the xmlns: part is stripped off
+ my $node = shift;
+ my %list;
+ foreach my $a (keys %{$node->getAttributes})
+ {
+ my $pre = $a;
+ if($pre=~s/^xmlns://)
+ {
+ $list{$pre} = $node->getAttribute ($a);
+ }
+ }
+ return %list;
+ }
+
+
+sub resolvePath
+ {
+ # return full path to 2nd arg relative to first (path or absolute URI)
+ my $base = shift;
+ my $path = shift;
+ if($path=~m,^/,) {return $path } # path is absolute, but has no drive. Let OS deal with it.
+ if($path=~s,^file:///([a-zA-Z]:/),$1,) {return $path } # file URI with drive letter
+ if($path=~m,^file://,) {return $path } # file URI with no drive letter (unit-style). Just pass on as is with leading / and let OS deal with it
+ if($path=~m,^[a-z0-9][a-z0-9]+:,i) {return $path } # absolute URI -- no idea how to handle, so just return
+ return &abspath(File::Basename::dirname($base)."/$path");
+ }
+
+
+sub resolveURI
+ {
+ # return full path to 2nd arg relative to first (path or absolute URI)
+ my $base = shift;
+ my $path = shift;
+ if($path=~m,[a-z0-9][a-z0-9]+:,i) {return $path } # absolute URI -- just return
+ if($path=~m,^/,) {return $path } # path is absolute, but has no drive. Let OS deal with it.
+ return &abspath(File::Basename::dirname($base)."/$path");
+ }
+
+sub localfile
+ {
+ my $file = shift;
+ if($file=~s,file:///([a-zA-Z]:/),$1,) {return $file } # file URI with drive letter
+ if($file=~m,file://,) {return $file } # file URI with no drive letter (unit-style). Just pass on as is with leading / and let OS deal with it
+ if($file=~m,^([a-z0-9][a-z0-9]+):,i)
+ {
+ print STDERR "ERROR: $1 scheme not supported\n";
+ return; # return empty string if not supported.
+ }
+ return $file
+ }
+
+sub namespaces
+ {
+ # return a list of namespace URI / prefix pairs, in the order they're defined
+ # these need to be used to define namespaces in the root element
+ my $file = shift;
+ my $node = shift;
+ my $type = $node->getNodeType;
+ if($type!=1) {return}
+ my $tag = $node->getTagName;
+ my @res;
+ my %nslist = &ns($node);
+ while(my($pre,$uri)=each(%nslist))
+ { # push all namespaces defined here onto the list
+ push(@res,$uri,$pre);
+ }
+ if($tag=~/^(layer|package|collection|component)$/ )
+ { # these have the potential of linking, so check for that
+ my $link= $node->getAttribute('href');
+ if($link)
+ {
+ $link=&resolvePath($file,$link);
+ if(-e $link)
+ {
+ my $doc = $parser->parsefile ($link);
+ my @docns = &namespaces($link,$doc->getDocumentElement);
+ undef $doc;
+ return (@res,@docns);
+ #ignore any children nodes if this is a link
+ }
+ print STDERR "Note: $link not found\n";
+ }
+ }
+ elsif($tag eq 'SystemDefinition' )
+ {
+ my $default = $node->getAttribute('id-namespace');
+ if($default)
+ {# mangle with a space so it's clear it's not a qname
+ push(@res,$default,'id namespace');
+ }
+ }
+ foreach my $item (@{$node->getChildNodes})
+ {
+ push(@res,&namespaces($file,$item));
+ }
+ return @res;
+ }
+
+sub processMeta
+ { # acts upon any known <meta> and strips it from the output if it's used
+ my $metanode = shift;
+
+ my $rel = $metanode->getAttribute('rel') || 'Generic';
+ if($rel eq 'config' && $config ne '')
+ { # only process if there is something to configure
+ &doconfig($metanode);
+ }
+ else
+ {
+ # do nothing. Not supported yet
+ }
+ }
+
+sub doCmpConfig
+ { # configure in or out the units in a component
+ my $cmp = shift; # the component node
+ my @unversioned; # list of all units with no version attribute (if more than one, they should all have filters defined)
+ my %versioned; # hash table of all units with a specified version, it's a fatal error to hav the same verison twice in one component
+ foreach my $item (@{$cmp->getChildNodes})
+ { # populate %versioned and @unversioned to save processsing later
+ if($item->getNodeType==1 && $item->getTagName eq 'unit')
+ {
+ my $ver = $item->getAttribute('version');
+ if($ver eq '') {push(@unversioned,$item)}
+ else
+ {
+ defined $versioned{$ver} && die "Cannot have more than one unit with version $ver in the same component ".$cmp->getAttribute('id');
+ $versioned{$ver}=$item;
+ }
+ }
+ }
+ my @picks = &getMetaConfigPick($cmp); # the list, in order, of all <pick> elements that affect this component
+ foreach my $pick (@picks)
+ {
+ my $ver = $pick->getAttribute('version');
+ if(!$versioned{$ver})
+ {
+ print STDERR "ERROR: Reference to invalid unit version $ver in component ",$cmp->getAttribute('id'),". Ignoring.\n";
+ return;
+ }
+ if(&definedMatches($pick))
+ { # remove all other units;
+ delete $versioned{$ver}; # to avoid removing in loop
+ foreach my $unit (@unversioned, values(%versioned))
+ {
+ $cmp->removeChild($unit);
+ print STDERR "Note: unit ",$unit->getAttribute('version')," in component " ,$cmp->getAttribute('id')," configured out\n";
+ }
+ last; # done. No more processing after first match
+ }
+ else
+ { # remove this unit and continue
+ $cmp->removeChild($versioned{$ver});
+ print STDERR "Note: unit $ver in component " ,$cmp->getAttribute('id')," configured out\n";
+ delete $versioned{$ver}; # gone, don't process anymore;
+ }
+ }
+ if (scalar(@unversioned, values(%versioned)) > 1)
+ {
+ print STDERR "Warning: component ",$cmp->getAttribute('id')," has more than one unit after configuration\n";
+ }
+ }
+
+
+sub getMetaConfigPick
+ { # return an array of all <pick> elements that affect the specified element
+ my $node = shift;
+ my @pick;
+ while($node->getParentNode->getNodeType==1)
+ {
+ foreach my $item (@{$node->getChildNodes})
+ {
+ my @picks;
+ if($item->getNodeType==1 && $item->getAttribute('rel') eq 'config')
+ { # it's conf metadata
+ foreach my $p (@{$item->getChildNodes})
+ {
+ if($p->getNodeType==1 && $p->getTagName eq 'pick') {push(@picks,$p)}
+ }
+ }
+ @pick=(@picks,@pick); # prepend this to the start;
+ }
+ $node=$node->getParentNode;
+ }
+ return @pick;
+ }
+
+sub definedMatches
+ { # process all <defined> and <not-defined> the specified element and return true or false if the combination matches
+ my $node = shift;
+ my $match = 1;
+ foreach my $def (@{$node->getChildNodes})
+ {
+ if($def->getNodeType == 1)
+ {
+ my $tag = $def->getTagName;
+ if($tag eq 'defined' or $tag eq 'not-defined')
+ {
+ my $var = $def->getAttribute('condition') || die "Must have condition set on all $tag elements";
+ $defineParams{$var} && die "Cannot use a macro with parameters as a feature flag: $var(".$defineParams{$var}->[0].")";
+ $match = $match && (($tag eq 'defined') ? defined($defines{$var}) : ! defined($defines{$var}));
+ }
+ }
+ }
+ return $match;
+ }
+
+sub doconfig
+ { # confgure in or out a system model item that owns the specified <meta>, remove the <meta> when done.
+ my $meta = shift;
+ my $keep = definedMatches($meta);
+ my $parent = $meta->getParentNode;
+ if(!$keep)
+ {
+ print STDERR "Note: ",$parent->getTagName," " ,$parent->getAttribute('id')," configured out\n";
+ $parent->getParentNode->removeChild($parent);
+ return; # it's removed, so there's nothing else we can possibly do
+ }
+
+ $parent->removeChild($meta);
+ }
+
+sub getDefines
+ { # populate the list of #defines from a specified .hrh file.
+ my $file = shift;
+ my $inc;
+ foreach my $i (@includes)
+ {
+ $inc.=" -I$i";
+ }
+ open(CPP,"cpp -dD$inc \"$file\"|");
+ while(<CPP>)
+ {
+ if(!/\S/){next} # skip blank lines
+ if(/^# [0-9]+ /) {next} # don't care about these
+ s/\s+$//;
+ if(s/^#define\s+(\S+)\((.*?)\)\s+//)
+ { #parametered define
+ push(@{$defineParams{$1}},@2,$_);
+ }
+ elsif(s/^#define\s+(\S+)//)
+ { # normal define
+ my $def = $1;
+ s/^\s+//;
+ $defines{$1}=$_;
+ }
+ else {die "cannot process $_";}
+ }
+ close CPP;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/joinsysdef.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Create a stand-alone sysdef from a linked set of fragments
+-->
+ <xsl:output method="xml" indent="yes"/>
+<!-- create a stand-alone sysdef from a linked set of fragments -->
+
+<xsl:param name="path">/os/deviceplatformrelease/foundation_system/system_model/system_definition.xml</xsl:param>
+
+<xsl:template match="/*">
+ <xsl:apply-templates select="." mode="join"/>
+</xsl:template>
+
+
+<xsl:template match="/SystemDefinition[systemModel]">
+<xsl:apply-templates select="." mode="join">
+ <xsl:with-param name="filename" select="$path"/>
+</xsl:apply-templates>
+</xsl:template>
+
+
+<xsl:template match="meta[@rel='Api']" priority="2" mode="meta"/> <!-- ignore these, not needed in system build -->
+
+
+<xsl:include href="joinsysdef-module.xsl"/>
+
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/mergesysdef-module.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,504 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ XSLT module for merging only two sysdef files according to the 3.0.0 rules. Old syntax not supported and must be converetd before calling.
+-->
+
+<xsl:variable name="defaultnamespace">http://www.symbian.org/system-definition</xsl:variable>
+
+<xsl:template match="/SystemDefinition[starts-with(@schema,'2.') or starts-with(@schema,'1.')]" priority="2" mode="merge-models">
+ <xsl:message terminate="yes">ERROR: Syntax <xsl:value-of select="@schema"/> not supported</xsl:message>
+</xsl:template>
+<xsl:template match="/SystemDefinition[not(systemModel)]" priority="2" mode="merge-models">
+ <xsl:message terminate="yes">ERROR: Can only merge stand-alone system models</xsl:message>
+</xsl:template>
+
+<!-- stuff for dealing with namespaces -->
+
+
+<xsl:template match="node()|@*" mode="translate-namespaces"><xsl:copy-of select="."/></xsl:template>
+<!-- don't translate meta or unit tags, just copy verbatim -->
+<xsl:template match="meta|unit" mode="translate-namespaces" priority="2">
+<xsl:element name="{name()}">
+<xsl:copy-of select="@*|*|comment()"/>
+</xsl:element>
+</xsl:template>
+
+<xsl:template match="*" mode="translate-namespaces"><xsl:param name="nsdoc"/>
+<xsl:element name="{name()}">
+<xsl:apply-templates select="@*|node()" mode="translate-namespaces">
+ <xsl:with-param name="nsdoc" select="$nsdoc"/>
+</xsl:apply-templates>
+</xsl:element>
+</xsl:template>
+
+
+<xsl:template match="@id|@before" mode="translate-namespaces"><xsl:param name="nsdoc"/>
+ <xsl:attribute name="{name()}">
+ <xsl:variable name="id">
+ <xsl:choose>
+ <xsl:when test="contains(.,':')">
+ <xsl:value-of select="substring-after(.,':')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="ns">
+ <xsl:choose>
+ <xsl:when test="contains(.,':')">
+ <xsl:value-of select="ancestor-or-self::*/namespace::*[name()=substring-before(current()/.,':')]"/>
+ </xsl:when>
+ <xsl:when test="/SystemDefinition/@id-namespace">
+ <xsl:value-of select="/SystemDefinition/@id-namespace"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$defaultnamespace"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="not($nsdoc/@id-namespace) and $defaultnamespace=$ns">
+ <xsl:value-of select="$id"/>
+ </xsl:when>
+ <xsl:when test="$nsdoc/@id-namespace=$ns">
+ <xsl:value-of select="$id"/>
+ </xsl:when>
+ <xsl:when test="$nsdoc/namespace::*[.=$ns]">
+ <xsl:value-of select="concat(name($nsdoc/namespace::*[.=$ns]),':',$id)"/>
+ </xsl:when>
+ <xsl:when test="/SystemDefinition/@id-namespace=$ns">
+ <xsl:variable name="myns">
+ <xsl:apply-templates mode="ns-prefix" select="$nsdoc">
+ <xsl:with-param name="ns" select="$ns"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:value-of select="concat($myns,':',$id)"/>
+ </xsl:when>
+ <xsl:otherwise> <!-- some namespace that needed to be defined -->
+ <xsl:message>Warning: need definition for namespace "<xsl:value-of select="$ns"/>" for <xsl:value-of select="$id"/></xsl:message>
+ <xsl:value-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition" mode="ns-prefix">
+ <xsl:param name="ns"/> <!-- the namespace URI -->
+ <xsl:param name="pre"/> <!-- the preferred prefix to use if possbile -->
+ <xsl:param name="dontuse"/> <!-- space prefixed, separated and terminated list of namespace prefixes to not use -->
+ <xsl:param name="chars">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</xsl:param> <!-- single letter namespace prefixes to try -->
+ <xsl:variable name="name" select="substring(substring-after($ns,'http://www.'),1,1)"/>
+ <xsl:choose>
+ <xsl:when test="$pre!='' and $pre!='id-namespace' and not(//namespace::*[name()=$pre]) and not(contains($dontuse,concat(' ',$pre,' ')))">
+ <xsl:value-of select="$pre"/>
+ </xsl:when>
+ <xsl:when test="$ns='' and $chars=''">
+ <xsl:message terminate="yes">ERROR: Cannot create namespace prefix for downstream default namespace in <xsl:value-of select="*/@id"/></xsl:message>
+ </xsl:when>
+ <xsl:when test="$name!='' and not(contains($dontuse,concat(' ',$name,' ')))"><xsl:value-of select="$name"/></xsl:when>
+ <xsl:when test="namespace::*[name()=substring($chars,1,1)] or contains($dontuse,concat(' ',substring($chars,1,1),' '))">
+ <xsl:apply-templates mode="ns-prefix">
+ <xsl:with-param name="chars" select="substring($chars,2)"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring($chars,1,1)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<!-- need to make sure this handles <meta> correctly -->
+
+<xsl:template match="/SystemDefinition" mode="merge-models">
+ <xsl:param name="other"/> <!-- the downstream SystemDefinition this is merged with -->
+ <xsl:param name="up" select="systemModel"/> <!-- the element containing the origin @name used for any component from "this" model. -->
+ <xsl:param name="down" select="$other/systemModel"/> <!-- the element containing origin @name used for any component from $other model. -->
+
+ <!-- do some testing -->
+ <xsl:if test="$other[starts-with(@schema,'2.') or starts-with(@schema,'1.')]">
+ <xsl:message terminate="yes">ERROR: Syntax <xsl:value-of select="$other/@schema"/> not supported</xsl:message>
+ </xsl:if>
+ <xsl:if test="not($other/systemModel)">
+ <xsl:message terminate="yes">ERROR: Can only merge stand-alone system models</xsl:message>
+ </xsl:if>
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/> <!-- use attributes from origin model -->
+ <xsl:variable name="namespaces">
+ <xsl:copy> <!-- needs <copy> so the processor doesn't lose the namespaces -->
+ <!--copy namespaces as needed -->
+
+ <xsl:copy-of select="namespace::*[name()!='xml']"/> <!-- all upstream namespaces -->
+
+ <xsl:variable name="cur" select="."/>
+ <xsl:for-each select="$other/namespace::*"> <!-- all namespaces in downstream not already in upstream -->
+ <xsl:if test="not((. = $cur/@id-namespace) or (not($cur/@id-namespace) and .= $defaultnamespace) or $cur/namespace::*[.=current()])">
+ <!-- namespace in downstream not in upstream doc -->
+ <xsl:variable name="newprefix">
+ <!-- test to see if the ns prefix already exists -->
+ <xsl:apply-templates select="$cur" mode="ns-prefix">
+ <xsl:with-param name="ns" select="."/>
+ <xsl:with-param name="pre" select="name()"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:copy/>
+ </xsl:if>
+ </xsl:for-each>
+
+ <xsl:if test="not(($other/@id-namespace = @id-namespace) or (not($other/@id-namespace) and not(@id-namespace)) or (not(@id-namespace) and $other/@id-namespace = $defaultnamespace) or namespace::*[.=$other/@id-namespace])">
+ <!-- default namespace in downstream not in upstream doc -->
+ <!-- need to make created ns a bit more intelligent -->
+ <xsl:attribute name="bar" namespace="{$other/@id-namespace}">
+ <xsl:value-of select="$other/@id-namespace"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:copy>
+ </xsl:variable>
+
+
+ <!-- copy the namespaces to currently open element (the root one) -->
+ <xsl:copy-of select="namespace::*"/>
+ <xsl:for-each select="$other/namespace::*[.!=current()/namespace::*]"><xsl:copy/></xsl:for-each>
+ <xsl:for-each select="exslt:node-set($namespaces)/*/namespace::*"><xsl:copy/></xsl:for-each>
+ <!-- translate all IDs in downstream doc to use namespaces from upstream doc
+ This is so much easier than having to propigate this info around while creating the doc-->
+ <xsl:variable name="otherdoc">
+ <xsl:apply-templates mode="translate-namespaces" select="$other">
+ <xsl:with-param name="nsdoc" select="exslt:node-set($namespaces)/* | ."/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:apply-templates mode="merge-models">
+ <xsl:with-param name="other" select="exslt:node-set($otherdoc)/*"/>
+ <xsl:with-param name="up" select="$up"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:apply-templates>
+
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="systemModel" mode="merge-models">
+ <xsl:param name="other"/> <!-- the parent of the downstream systemModel this is merged with -->
+ <xsl:param name="up"/>
+ <xsl:param name="down"/>
+ <xsl:copy><xsl:copy-of select="@*"/>
+ <!-- copy metas and comments in between meta. Do not try to merge metadata between models -->
+ <xsl:copy-of select="meta | $other/systemModel/meta | comment()[following-sibling::meta]"/>
+ <xsl:apply-templates mode="merge-models">
+ <xsl:with-param name="other" select="$other/systemModel"/>
+ <xsl:with-param name="up" select="$up"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:apply-templates>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="@*|*|comment()" mode="merge-models"><xsl:copy-of select="."/></xsl:template>
+
+
+<xsl:template match="meta|comment()[following-sibling::meta]" mode="merge-models"/>
+ <!-- copy elesewhere, not here so that metas always appear first-->
+
+
+
+<!-- merge levels attribute via std rules -->
+<xsl:template match="layer/@levels|package/@levels" mode="merge-models">
+ <xsl:param name="other"/><!-- the element contains the other @levels -->
+ <xsl:choose>
+ <!-- if they are the same, or not specified in the other, just copy -->
+ <xsl:when test=".=$other/@levels or not($other/@levels)"><xsl:copy-of select="."/></xsl:when>
+ <xsl:when test="contains(concat(' ',normalize-space(.),' '),concat(' ',normalize-space($other/@levels),' '))">
+ <!--upstream completely contains downstream, just copy -->
+ <xsl:copy-of select="."/>
+ </xsl:when>
+ <xsl:when test="contains(concat(' ',normalize-space($other/@levels),' '),concat(' ',normalize-space(.),' '))">
+ <!-- If this is contained is other, then use other-->
+ <xsl:copy-of select="$other/@levels"/>
+ </xsl:when>
+ <xsl:when test="contains(concat(' ',normalize-space($other/@levels),' '),' - ')">
+ <!-- if other uses + syntax, then pre/append -->
+ <xsl:variable name="lev">
+ <xsl:value-of select="substring-before(concat(' ',normalize-space($other/@levels),' '),' - ')"/>
+ <xsl:value-of select="concat(' ',.,' ')"/>
+ <xsl:value-of select="substring-after(concat(' ',normalize-space($other/@levels),' '),' - ')"/>
+ </xsl:variable>
+ <xsl:attribute name="levels"><xsl:value-of select="normalize-space($lev)"/></xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise> <!-- if they differ, use the origin's levels -->
+ <xsl:message>Note: levels differ "<xsl:value-of select="."/>" vs "<xsl:value-of select="$other/@levels"/>"</xsl:message>
+ <xsl:copy-of select="."/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="copy-sorted-content">
+ <xsl:param name="base"/>
+ <xsl:param name="to-sort"/>
+ <xsl:param name="start"/>
+ <xsl:param name="end"/>
+ <xsl:param name="down"/>
+ <xsl:param name="remainder" select="/.."/>
+
+ <xsl:choose>
+ <xsl:when test="not($to-sort)"/> <!-- nothing left to copy. stop -->
+ <xsl:when test="not($base)"/> <!-- reached end. stop -->
+ <xsl:when test="$base[1]/@id=$end/following-sibling::*[1]/@id"/> <!-- passed $end. Stop -->
+ <xsl:when test="$base[1]/@id = $to-sort[1]/@id"> <!-- both lists start with same item -->
+ <xsl:if test="$base[1]/@id!=$end/@id"> <!-- not at end, so keep going -->
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="$base[position() != 1]"/>
+ <xsl:with-param name="to-sort" select="$to-sort[position() != 1]"/>
+ <xsl:with-param name="remainder" select="$remainder"/>
+ <xsl:with-param name="start" select="$start"/>
+ <xsl:with-param name="end" select="$end"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:when>
+ <xsl:when test="$remainder[@id = $base[1]/@id]"> <!-- left over item is in $base -->
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="$base[position() != 1]"/>
+ <xsl:with-param name="to-sort" select="$to-sort"/>
+ <xsl:with-param name="remainder" select="$remainder[@id != $base[1]/@id]"/>
+ <xsl:with-param name="start" select="$start"/>
+ <xsl:with-param name="end" select="$end"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($base[@id = $to-sort[1]/@id])"> <!-- in to-sort, but not base -->
+ <xsl:if test="$base[1]/@id=$end/@id and not($base[@id=$to-sort[1]/@before])">
+ <!-- if at end, then this needs to be copied
+ don't copy if the before ID is found in $base -->
+ <xsl:apply-templates mode="merge-copy-of" select="$to-sort[1]">
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$end/ancestor::systemModel"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="$base"/>
+ <xsl:with-param name="to-sort" select="$to-sort[position() != 1]"/>
+ <xsl:with-param name="remainder" select="$remainder"/>
+ <xsl:with-param name="start" select="$start"/>
+ <xsl:with-param name="end" select="$end"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($to-sort[@id = $base[1]/@id])"> <!-- in base, but not to-sort -->
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="$base[position() != 1]"/>
+ <xsl:with-param name="to-sort" select="$to-sort"/>
+ <xsl:with-param name="remainder" select="$remainder"/>
+ <xsl:with-param name="start" select="$start"/>
+ <xsl:with-param name="end" select="$end"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$base[@id = $to-sort[1]/@id]"> <!-- is in base, but not 1st one-->
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="$base"/>
+ <xsl:with-param name="to-sort" select="$to-sort[position() != 1] "/>
+ <xsl:with-param name="remainder" select="$remainder | $to-sort[1]"/>
+ <xsl:with-param name="start" select="$start"/>
+ <xsl:with-param name="end" select="$end"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="layer | package | collection | component" mode="merge-models">
+ <xsl:param name="other"/> <!-- the downstream item of the parent's rank that contains a potential items this is merged with -->
+ <xsl:param name="up"/>
+ <xsl:param name="down"/>
+ <xsl:variable name="this" select="."/> <!-- current item -->
+
+ <!-- match = this item in the downstream model -->
+ <xsl:variable name="match" select="$other/*[@id=current()/@id]"/>
+
+ <!-- prev = the previous item before the current one (no metas, only named items)-->
+ <xsl:variable name="prev" select="preceding-sibling::*[@id][1]"/>
+
+ <!-- copy all items between this and prev that are solely in the downstream model -->
+
+ <xsl:choose>
+ <xsl:when test="$match and (not($prev) or $other/*[@id= $prev/@id] )">
+ <xsl:call-template name="copy-sorted-content">
+ <xsl:with-param name="base" select="../*[@id]"/>
+ <xsl:with-param name="to-sort" select="$other/*[@id]"/>
+ <xsl:with-param name="start" select="$prev"/>
+ <xsl:with-param name="end" select="."/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($match/preceding-sibling::*[@id=$this/../*/@id]) and $other/*[@id= current()/@id]/preceding-sibling::*[@id and not(@before)]">
+ <!-- if this is the first item in other that's also in this, then put all new items from other here -->
+ <xsl:apply-templates mode="merge-copy-of" select="$match/preceding-sibling::*[@id and not(@before)]">
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$this/ancestor::systemModel"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ </xsl:choose>
+
+ <!-- just copy anything identified as being before this, assume they're all ok -->
+ <xsl:apply-templates mode="merge-copy-of" select="$other/*[@before=current()/@id]">
+ <xsl:with-param name="remove-before" select="1"/>
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$this/ancestor::systemModel"/>
+ </xsl:apply-templates>
+
+
+ <xsl:copy>
+ <xsl:apply-templates select="@*" mode="merge-models"> <!-- copy upstream attributes -->
+ <xsl:with-param name="other" select="$match"/>
+ </xsl:apply-templates>
+
+ <xsl:if test="self::component and not(@origin-model) and $up/@name">
+ <!-- insert origin-model and optional root for components only -->
+ <xsl:attribute name="origin-model">
+ <xsl:value-of select="$up/@name"/>
+ </xsl:attribute>
+ <xsl:if test="not(@root)">
+ <xsl:copy-of select="$up/@root"/>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:for-each select="$match/@*"> <!-- copy downstream attributes, only if not set on upstream -->
+ <xsl:if test="not($this/@*[name()=name(current())])"><xsl:copy-of select="."/></xsl:if>
+ </xsl:for-each>
+
+ <xsl:choose>
+ <xsl:when test="self::component">
+ <!-- copy all units, metas and comments from this
+ copy all metas in the merged component
+ copy any new comments in the merged component (not duplicates)
+ if there are no units in the this, copy all units in the merged component
+ if there are units in this, copy only the versioned units in the merged component (only those versions not already specified) -->
+ <xsl:copy-of select="*|comment() | $match/meta |$match/unit[not($this/unit)] | $match/unit[$this/unit and @version[.!=$this/unit/@version]] | $match/comment()[.!=$this/comment()]"/>
+ </xsl:when>
+ <xsl:otherwise>
+
+ <!-- copy metas and comments in between meta. Do not try to merge metadata between models -->
+ <xsl:copy-of select="meta | $match/meta | comment()[following-sibling::meta]"/>
+
+ <xsl:apply-templates mode="merge-models">
+ <xsl:with-param name="other" select="$match"/>
+ <xsl:with-param name="up" select="$up"/>
+ <xsl:with-param name="down" select="$down"/>
+ </xsl:apply-templates>
+ <!-- don't copy if explicitly or implicitly placed already-->
+ <xsl:for-each select="$match/*[not(@before) and not(following-sibling::*[@id=$this/*/@id])]">
+ <xsl:if test="not($this/*[@id=current()/@id])">
+ <xsl:apply-templates mode="merge-copy-of" select=".">
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$this/ancestor::systemModel"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:copy>
+
+ <xsl:if test="self::layer and not(following-sibling::layer)">
+ <!-- for the last layer, tack on any remaining layers -->
+ <xsl:apply-templates mode="merge-copy-of" select="$other/layer[not(@before) and not(following-sibling::*[@id=$this/../layer/@id]) and not(@id=$this/../layer/@id)]">
+ <xsl:with-param name="origin" select="$down"/>
+ <xsl:with-param name="root" select="$this/ancestor::systemModel"/>
+ </xsl:apply-templates>
+ </xsl:if>
+</xsl:template>
+
+
+
+<xsl:template match="*" mode="merge-copy-of">
+ <xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
+ <xsl:param name="origin"/> <!--the element containing the @name to use the origin-model attribute -->
+ <xsl:param name="root"/> <!--the systemModel element in the upstream doc -->
+
+ <xsl:choose>
+ <!-- this might slow things down, consider making optional -->
+ <xsl:when test="not(self::layer) and count($root/descendant::*[name()=name(current()/..) and @id!=current()/../@id]/*[@id=current()/@id])">
+ <xsl:message>Warning: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" moved in downstream model. Ignoring moved <xsl:value-of select="name()"/>
+ <xsl:text>
</xsl:text>
+ </xsl:message>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- save all content in a variable to test to see if it's got any problems (ie been removed due to errors)-->
+ <xsl:variable name="content">
+ <xsl:apply-templates select="*|comment()" mode="merge-copy-of">
+ <xsl:with-param name="origin" select="$origin"/>
+ <xsl:with-param name="root" select="$root"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:choose>
+ <!-- if all elements in this have been deleted, throw out this element -->
+ <xsl:when test="not(exslt:node-set($content)/*) and *">
+ <xsl:message>Warning: All content in downstream <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" is invalid. Ignoring <xsl:value-of select="name()"/>
+ <xsl:text>
</xsl:text>
+ </xsl:message>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:choose>
+ <xsl:when test="$remove-before">
+ <xsl:copy-of select="@*[name()!='before']"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:copy-of select="exslt:node-set($content)"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="comment()|@*" mode="merge-copy-of">
+ <xsl:copy-of select="."/>
+</xsl:template>
+
+<xsl:template match="component" mode="merge-copy-of">
+ <xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
+ <xsl:param name="origin"/> <!--the element containing the @name to use the origin-model attribute -->
+ <xsl:param name="root"/> <!--the systemModel element in the upstream doc -->
+
+ <xsl:choose>
+ <!-- this might slow things down, consider making optional -->
+ <xsl:when test="$root/descendant::collection[@id!=current()/../@id]/component[@id=current()/@id]">
+ <xsl:message>Warning: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" moved in downstream model. Ignoring moved <xsl:value-of select="name()"/>
+ <xsl:text>
</xsl:text>
+ </xsl:message>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:choose>
+ <xsl:when test="$remove-before">
+ <xsl:copy-of select="@*[name()!='before']"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="not(@origin-model) and $origin/@name">
+ <xsl:attribute name="origin-model">
+ <xsl:value-of select="$origin/@name"/>
+ </xsl:attribute>
+ <xsl:if test="not(@root)">
+ <xsl:copy-of select="$origin/@root"/>
+ </xsl:if>
+ </xsl:if>
+ <xsl:copy-of select="*|comment()"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/mergesysdef.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,100 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Merge two 3.x syntax system definitions
+-->
+
+ <xsl:output method="xml" indent="yes"/>
+ <xsl:param name="Downstream">mcl/System_Definition_Template.xml</xsl:param>
+ <xsl:key name="origin" match="component" use="@origin-model"/>
+
+<!-- only supports 3.x syntax and only operates on stand-alone models -->
+
+<xsl:variable name="downstream" select="document($Downstream,.)/SystemDefinition"/>
+<xsl:param name="upname">
+ <xsl:choose>
+ <xsl:when test="$downstream[starts-with(@schema,'2.') or starts-with(@schema,'1.') or not(systemModel)]">
+ <xsl:message terminate="yes">Syntax <xsl:value-of select="@schema"/> not supported</xsl:message>
+ </xsl:when>
+ <xsl:when test="/SystemDefinition/systemModel/@name=$downstream/systemModel/@name">
+ <xsl:apply-templates mode="origin-term" select="/*">
+ <xsl:with-param name="root">Upstream</xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="/SystemDefinition/systemModel/@name"/></xsl:otherwise>
+ </xsl:choose>
+</xsl:param>
+
+<xsl:param name="downname">
+ <xsl:choose>
+ <xsl:when test="/SystemDefinition/systemModel/@name=$downstream/systemModel/@name">
+ <xsl:apply-templates mode="origin-term" select="$downstream">
+ <xsl:with-param name="root">Downstream</xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$downstream/systemModel/@name"/></xsl:otherwise>
+ </xsl:choose>
+</xsl:param>
+
+<xsl:template mode="origin-term" match="*">
+ <xsl:param name="root"/>
+ <xsl:param name="index"/>
+ <xsl:choose>
+ <xsl:when test="not(key('origin',concat($root,$index)))">
+ <xsl:value-of select="concat($root,$index)"/>
+ </xsl:when>
+ <xsl:when test="$index=''">
+ <xsl:apply-templates mode="origin-term" select=".">
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="index" select="1"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="origin-term" select=".">
+ <xsl:with-param name="root" select="$root"/>
+ <xsl:with-param name="index" select="$index + 1"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<!-- this merge only two files according to the 3.0.0 rules. Old syntax not supported. Must be converetd before calling -->
+
+
+
+<xsl:template match="/*">
+ <xsl:variable name="upmodel">
+ <sysdef name="{$upname}"/>
+ </xsl:variable>
+ <xsl:variable name="downmodel">
+ <sysdef name="{$downname}"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="function-available('exslt:node-set')">
+ <xsl:apply-templates mode="merge-models" select=".">
+ <xsl:with-param name="other" select="$downstream"/>
+ <xsl:with-param name="up" select="exslt:node-set($upmodel)/sysdef"/>
+ <xsl:with-param name="down" select="exslt:node-set($downmodel)/sysdef"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise> <!-- no node set funcion, so don't bother setting the names -->
+ <xsl:apply-templates mode="merge-models" select=".">
+ <xsl:with-param name="other" select="$downstream"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:include href="mergesysdef-module.xsl"/>
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/readme.txt Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,21 @@
+Filtering tools:
+filtering.xsl - Filter a sysdef in the 2.0 or 3.0 syntax
+ filter-module.xsl - XSLT module which contains the logic to process the filter attribute in the system definition
+
+Joining tools:
+joinsysdef.pl - Create a stand-alone sysdef from a linked set of fragments. Supports confguring via an .hrh file.
+joinsysdef.xsl - Create a stand-alone sysdef from a linked set of fragments
+joinandparesysdef.xsl - Create a stand-alone sysdef from a linked set of fragments, paring down to just a set of items of the desired rank.
+ joinsysdef-module.xsl - XSLT module which contains the logic to join a system definition file
+
+Merging tools:
+mergesysdef.xsl - Merge two 3.x syntax stand-alone system definitions
+ mergesysdef-module.xsl - XSLT module for merging only two sysdef files according to the 3.0.0 rules
+
+Other Tools:
+sysdefdowngrade.xsl - Convert a 3.0.0 sysdef to 2.0.1 sytnax
+
+XSLT Processing:
+xalan.jar
+xercesImpl.jar
+xml-apis.jar
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/rootsysdef.pl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,744 @@
+use strict;
+
+
+use FindBin; # for FindBin::Bin
+use lib $FindBin::Bin;
+use lib "$FindBin::Bin/lib";
+
+use Cwd;
+use Cwd 'abs_path';
+use Getopt::Long;
+use File::Basename;
+use File::Spec;
+use XML::DOM;
+
+my $output;
+my $path;
+my $defaultns = 'http://www.symbian.org/system-definition'; # needed if no DTD
+my @searchpaths;
+my @searchroots;
+my %additional;
+my %add;
+my %newNs;
+my $warning = "Error";
+my $placeholders=0;
+
+my @tdOrder =("hb","se", "lo","dc", "vc" , "pr", "dm", "de", "mm", "ma" , "ui", "rt", "to" );
+
+# need to add options for controlling which metas are filtered out and which are included inline
+GetOptions
+ (
+ 'path=s' => \$path,
+ 'output=s' => \$output,
+ 'w=s' => \$warning,
+ 'root=s' => \@searchroots,
+ 'glob=s' => \@searchpaths,
+ 'placeholders=s' => \$placeholders
+ );
+
+
+ if($path eq '') {$path = '/os/deviceplatformrelease/foundation_system/system_model/system_definition.xml'}
+
+if(!($warning =~/^(Note|Warning|Error)$/)) {$warning="Error"}
+
+# path is the system model path of the processed sysdef file. This is only used when creating a stand-alone sysdef as the output
+# output specifies the file this is saved in. If specified, all (relative) paths will be modified to be relative to it. If not, all paths will be absolute
+# w is the warning level: Note, Warning or Error.
+# root = -root g:\sf
+# glob = -glob "\*\*\package_definition.xml"
+
+#rootsysdef.pl -root F:\dev\personal\sftest\sf\mcl -glob "\*\*\package_definition.xml" -output ..\..\..\deviceplatformrelease\nokia_system\system_definition.sf.xml ..\..\..\deviceplatformrelease\foundation_system\system_model\system_definition.xml
+
+my %replacefile;
+my $dir;
+foreach(@searchpaths)
+ {
+ my $ndir = shift(@searchroots);
+ if($ndir ne '') {$dir=$ndir}
+ foreach my $file (glob "$dir$_")
+ {
+ my $map =substr($file,length($dir));
+ $map=~tr/\\/\//;
+ $additional{$map}=$file;
+ $replacefile{&abspath($file)}=$map;
+ $add{&abspath($file)}=1;
+ }
+ }
+
+my $sysdef = &abspath(shift); # resolve the location of the root sysdef
+
+# rootmap is a mapping from the filesystem to the paths in the doc
+my %rootmap = &rootMap($path,$sysdef);
+my %nsmap;
+my %urimap;
+
+
+
+my $parser = new XML::DOM::Parser;
+my $sysdefdoc = $parser->parsefile ($sysdef);
+
+my $mapmeta;
+my $modpath;
+if($output eq '')
+ { #figure out mapping path
+ my @fspath = split(/[\\\/]/,$sysdef);
+ my @smpath = split(/[\\\/]/,$path);
+ while(lc($smpath[$#smpath]) eq lc($fspath[$#fspath] )) {
+ pop(@smpath);
+ pop(@fspath);
+ }
+ my $mappath = join('/',@fspath);
+ my $topath = join('/',@smpath);
+ $mappath=~s,^/?,file:///,;
+ $mapmeta = $sysdefdoc->createElement('meta');
+ $mapmeta->setAttribute('rel','link-mapping');
+ my $node = $sysdefdoc->createElement('map-prefix');
+ $node->setAttribute('link',$mappath);
+ $topath ne '' && $node->setAttribute('to',$topath);
+ $mapmeta->appendChild($node);
+ }
+else
+ {
+ $modpath = &relativeTo(&abspath($output), $sysdef);
+ }
+
+
+# find all the namespaces used in all trhe fragments and use that
+# to set the namespaces ni the root element of the created doc
+# should be able to optimise by only parsing each doc once and
+# maybe skipping the contends of <meta>
+my @nslist = &namespaces($sysdef,$sysdefdoc->getDocumentElement());
+
+my %replacing;
+my %newContainer;
+my %foundDescendants;
+
+foreach(keys %add)
+ {
+ my $fragment = $parser->parsefile ($_);
+ my $fdoc = $fragment->getDocumentElement();
+ my $topmost =&firstElement($fdoc);
+ my $type = $topmost->getTagName;
+ my $id = $topmost->getAttribute('id');
+ my ($localid,$ns) = &idns($topmost,$id);
+ my @path = &guessIdInPath($localid,$_);
+ if($type eq 'layer') {@path=@path[0]}
+ elsif($type eq 'package') {@path=@path[0..1]}
+ elsif($type eq 'collection') {@path=@path[0..2]}
+ elsif($type eq 'component') {@path=@path[0..3]}
+ @path = reverse(@path);
+ $add{$_}=join('/',@path)." $localid $ns";
+ $replacing{$type}->{"$localid $ns"} = $_;
+ # keys with a space are namespaced and fully identified, and contain the filename as the content.
+ # keys with no space have unknown namespace and contain a hash of the content
+ $newContainer{join('/',@path[0..$#path-1])}->{"$localid $ns"} = $_;
+ for(my $i=-1;$i<$#path-1;$i++)
+ {
+ $foundDescendants{$path[$i+1]}=1;
+ $newContainer{join('/',@path[0..$i])}->{$path[$i+1]}=1;
+ }
+ }
+
+
+while(@nslist)
+ {
+ my $uri = shift(@nslist);
+ my $prefix =shift(@nslist);
+ if($prefix eq 'id namespace'){$prefix=''}
+ if(defined $urimap{$uri}) {next} # already done this uri
+ $urimap{$uri} = $prefix;
+ if($nsmap{$prefix})
+ { # need a new prefix for this, guess from the URI (for readability)
+ if($uri=~/http:\/\/(www\.)?([^.\/]+)\./) {$prefix = $2}
+ my $i=0;
+ while($nsmap{$prefix})
+ { # still no prefix, just make up
+ $prefix="ns$i";
+ $i++;
+ # next line not really necessary, but it's a good safety to stop infinite loops
+ $i eq 1000 && die "ERROR: cannot create namespace prefix for $uri";
+ }
+ }
+ $nsmap{$prefix}=$uri;
+ }
+
+my $docroot = $sysdefdoc->getDocumentElement;
+
+my $ns = $docroot->getAttribute('id-namespace');
+if(!$ns && $nsmap{''})
+ {
+ $docroot->setAttribute('id-namespace',$nsmap{''});
+ }
+while(my($pre,$uri) = each(%nsmap))
+ {
+ $pre ne '' || next ;
+ $docroot->setAttribute("xmlns:$pre",$uri);
+ }
+
+&walk($sysdef,$docroot);
+
+if($output eq '')
+ {
+ print $sysdefdoc->toString;
+ }
+else
+ {
+ $sysdefdoc->printToFile($output);
+ }
+
+
+sub abspath
+ {
+ # normalize the path into an absolute one
+ my ($name,$path) = fileparse($_[0]);
+ if($path eq '' && $name eq '') {return};
+ $path=~tr,\\,/,;
+ if( -e $path)
+ {
+ return abs_path($path)."/$name";
+ }
+ my @dir = split('/',$_[0]);
+ my @new;
+ foreach my $d (@dir)
+ {
+ if($d eq '.') {next}
+ if($d eq '..')
+ {
+ pop(@new);
+ next;
+ }
+ push(@new,$d)
+ }
+ return join('/',@new);
+ }
+
+
+
+sub normpath
+ {
+ # normalize the path
+ my @norm;
+ foreach my $dir(split(/[\\\/]/,shift)) {
+ if($dir eq '.') {next}
+ if($dir eq '..')
+ {
+ if($#norm == -1 || $norm[$#norm] eq '..')
+ { # keep as is
+ push(@norm,$dir);
+ }
+ elsif($#norm == 0 && $norm[0] eq '')
+ { # path begins with /, interpret /.. as just / -- ie toss out
+ next
+ }
+ else
+ {
+ pop(@norm);
+ }
+ }
+ else
+ {
+ push(@norm,$dir);
+ }
+ }
+
+ return join('/',@norm)
+ }
+
+
+sub rootMap {
+ my @pathdirs = split(/\//,$_[0]);
+ my @rootdirs = split(/\//,$_[1]);
+
+ while(lc($rootdirs[$#rootdirs]) eq lc($pathdirs[$#pathdirs]) )
+ {
+ pop(@rootdirs);
+ pop(@pathdirs);
+ }
+ return (join('/',@rootdirs) => join('/',@pathdirs) );
+ }
+
+sub replacedBy
+ { # can only check once. Destroys data
+ my $node = shift;
+ my $fullid= join(' ',&idns($node));
+ my $type = $node->getTagName;
+ my $repl = $replacing{$type}->{$fullid};
+ delete $replacing{$type}->{$fullid};
+ return $repl;
+ }
+
+sub walk
+ {
+ #' walk through the doc, resolving all links
+ my $file = shift;
+ my $node = shift;
+ my $type = $node->getNodeType;
+ if($type!=1) {return}
+ my $tag = $node->getTagName;
+ if($tag=~/^(layer|package|collection|component)$/ )
+ {
+ if($file eq $sysdef)
+ {
+ &fixIDs($node); # normalise all IDs in the root doc.
+ }
+ my $override = &replacedBy($node);
+ my $link= $node->getAttribute('href');
+ if($override eq '' )
+ {
+ my ($id,$ns)=&idns($node);
+ if($foundDescendants{$id})
+ { # keep this node, it'll be populated by what we found
+ if($link)
+ {
+ $node->removeAttribute('href');
+ }
+ }
+ elsif($link || !$placeholders)
+ { # not going to be used, remove
+ $node->getParentNode->removeChild($node) ; # not present, remove
+ return;
+ }
+ }
+ else
+ {
+ my $href = $node->getAttribute('href');
+ my $ppath = join('/',&parentPath($node->getParentNode));
+ delete $newContainer{$ppath}->{join(' ',&idns($node))}; # remove this from list of things which need to be added
+ if(&resolvePath($file,$href) ne $override)
+ { # file has changed, update
+ print STDERR "$warning: Replacing $tag ",$node->getAttribute('id')," with $override\n";
+ &setHref($node,$override);
+ return;
+ }
+ }
+ my @curpath = &parentPath($node);
+ my $curitem = $curpath[$#curpath];
+ my $curp = join('/',@curpath[0..$#curpath-1]);
+ delete $newContainer{$curp}->{$curitem};
+
+ if($link)
+ {
+ foreach my $child (@{$node->getChildNodes}) {$node->removeChild($child)} # can't have children
+ &fixHref($node,$file);
+ return;
+ }
+ }
+ elsif($tag eq 'systemModel' && $mapmeta)
+ { # need absolute paths for all links
+ $node->insertBefore ($mapmeta,$node->getFirstChild);
+ }
+ elsif($tag=~/^(SystemDefinition|systemModel)$/ )
+ {
+ }
+ elsif($tag eq 'unit')
+ {
+ foreach my $atr ('bldFile','mrp','base','proFile')
+ {
+ my $link= $node->getAttribute($atr);
+ if($link && !($link=~/^\//))
+ {
+ if($mapmeta)
+ { # use absolute paths
+ $link= &abspath(File::Basename::dirname($file)."/$link");
+ foreach my $a (keys %rootmap)
+ {
+ $link=~s,^$a,$rootmap{$a},ie;
+ }
+ }
+ else
+ { # modified relative path
+ $link = &normpath($modpath.$link);
+ }
+ $node->setAttribute($atr,$link);
+ }
+ }
+ }
+ elsif($tag eq 'meta')
+ {
+ &fixHref($node,$file);
+ &processMeta($node);
+ next;
+ }
+ else {return}
+ foreach my $item (@{$node->getChildNodes})
+ {
+ #print $item->getNodeType,"\n";
+ &walk($file,$item);
+ }
+ if($tag=~/^(systemModel|layer|package|collection|component)$/ )
+ { # check for appending
+ my $ppath = join('/',&parentPath($node));
+ if($newContainer{$ppath}) {
+ foreach my $item (sort keys %{$newContainer{$ppath}})
+ {
+ &appendNewItem($node,$item,$newContainer{$ppath}->{$item});
+ }
+ }
+ }
+ }
+
+
+sub getNs
+ {
+ # find the ns URI that applies to the specified prefix.
+ my $node = shift;
+ my $pre = shift;
+ my $uri = $node->getAttribute("xmlns:$pre");
+ if($uri) {return $uri}
+ my $parent = $node->getParentNode;
+ if($parent && $parent->getNodeType==1)
+ {
+ return getNs($parent,$pre);
+ }
+ }
+
+
+sub fixIDs
+ {
+ # translate the ID to use the root doc's namespaces
+ my $node = shift;
+ foreach my $id ('id','before')
+ {
+ &fixID($node,$id);
+ }
+}
+
+sub idns
+ { # return the namespace of an ID
+ my $node = shift;
+ my $id = shift;
+ if($id eq '' ) {$id = $node->getAttribute('id'); }
+ if($id=~s/^(.*)://)
+ { # it's got a ns, find out what it is
+ my $pre = $1;
+ return ($id,&getNs($node,$pre));
+ }
+ return ($id,$node->getOwnerDocument->getDocumentElement->getAttribute("id-namespace") || $defaultns);
+ }
+
+sub fixID
+ {
+ # translate the ID to use the root doc's namespaces
+ my $node = shift;
+ my $attr = shift || 'id';
+ my $id = $node->getAttribute($attr);
+ if($id eq '') {return}
+ my $ns;
+ if($id=~s/^(.*)://)
+ { # it's got a ns, find out what it is
+ my $pre = $1;
+ $ns=&getNs($node,$pre);
+ }
+ else
+ {
+ $ns = $node->getOwnerDocument->getDocumentElement->getAttribute("id-namespace") ||
+ $defaultns;
+ }
+ $ns = $urimap{$ns};
+ $id = ($ns eq '') ? $id : "$ns:$id";
+ return $node->setAttribute($attr,$id);
+}
+
+sub firstElement {
+ # return the first element in this node
+ my $node = shift;
+ foreach my $item (@{$node->getChildNodes}) {
+ if($item->getNodeType==1) {return $item}
+ }
+}
+
+
+sub atts {
+ # return a hash of all attribtues defined for this element
+ my $node = shift;
+ my %at = $node->getAttributes;
+ my %list;
+ foreach my $a (keys %{$node->getAttributes})
+ {
+ if($a ne '')
+ {
+ $list{$a} = $node->getAttribute ($a);
+ }
+ }
+ return %list;
+}
+
+
+sub ns
+ {
+ # return a hash of ns prefix and uri -- the xmlns: part is stripped off
+ my $node = shift;
+ my %list;
+ foreach my $a (keys %{$node->getAttributes})
+ {
+ my $pre = $a;
+ if($pre=~s/^xmlns://)
+ {
+ $list{$pre} = $node->getAttribute ($a);
+ }
+ }
+ return %list;
+ }
+
+
+
+sub namespaces
+ {
+ # return a list of namespace URI / prefix pairs, in the order they're defined
+ # these need to be used to define namespaces in the root element
+ my $file = shift;
+ my $node = shift;
+ my $type = $node->getNodeType;
+ if($type!=1) {return}
+ my $tag = $node->getTagName;
+ my @res;
+ my %nslist = &ns($node);
+ while(my($pre,$uri)=each(%nslist))
+ { # push all namespaces defined here onto the list
+ push(@res,$uri,$pre);
+ }
+ if($tag=~/^(layer|package|collection|component)$/ )
+ { # these have the potential of linking, so check for that
+ }
+ elsif($tag eq 'SystemDefinition' )
+ {
+ my $default = $node->getAttribute('id-namespace');
+ if($default)
+ {# mangle with a space so it's clear it's not a qname
+ push(@res,$default,'id namespace');
+ }
+ }
+ foreach my $item (@{$node->getChildNodes})
+ {
+ push(@res,&namespaces($file,$item));
+ }
+ return @res;
+ }
+
+sub processMeta
+ {
+ my $metanode = shift;
+ # do nothing. Not supported yet
+ }
+
+sub guessIdInPath
+ {
+ my $id = shift;
+ my @path = reverse(split(/\//,shift));
+ while(@path)
+ {
+ my $dir = shift(@path);
+ if($dir eq $id)
+ {
+ return ($id,@path);
+ }
+ }
+ }
+
+
+sub parentPath
+ {
+ my $node=shift;
+ my @path;
+ while($node)
+ {
+ if(!$node) {return @path}
+ my $id=$node->getAttribute('id');
+ if($id eq '') {return @path}
+ $id=~s/^.*://;
+ @path = ($id,@path);
+ $node = $node->getParentNode();
+ }
+ return @path;
+ }
+
+sub childTag
+ {
+ my $tag = shift;
+ if($tag eq 'systemModel') {return 'layer'}
+ if($tag eq 'layer') {return 'package'}
+ if($tag eq 'package') {return 'collection'}
+ if($tag eq 'collection') {return 'component'}
+ die "ERROR: no child for $tag";
+ }
+
+sub appendNewItem
+ {
+ my $node = shift;
+ my $doc = $node->getOwnerDocument;
+ my $id = shift;
+ my $fullid=$id;
+ my $contents = shift;
+ my $tag = &childTag($node->getTagName());
+ my $new = $doc->createElement($tag);
+ if($id=~/^(.*) (.*)/)
+ {
+ $id=$1;
+ $ns = getNamespacePrefix($node,$2);
+ if($ns ne '') {$id="$ns:$id"}
+ }
+ else
+ {
+ $contents = '';
+ }
+ $new->setAttribute('id',$id); # default namespace
+ $node->appendChild($new);
+ my $ppath = join('/',&parentPath($new));
+ if($contents eq '')
+ { # look for additions
+ print STDERR "$warning: Adding new $tag: $id\n";
+ if($newContainer{$ppath}) {
+ foreach my $item (sort keys %{$newContainer{$ppath}})
+ {
+ &appendNewItem($new,$item,$newContainer{$ppath}->{$item});
+ }
+ }
+ }
+ else
+ { # this one item is defined in the specified file
+ if($tag eq 'package')
+ { #include some package data in root
+ my $fragment = $parser->parsefile ($contents);
+ my $fdoc = $fragment->getDocumentElement();
+ my $topmost =&firstElement($fdoc);
+ my %at = &atts($topmost);
+ foreach my $arg ('tech-domain','level','span')
+ {
+ if($at{$arg}) { $new->setAttribute($arg,$at{$arg})}
+ }
+ if($at{'tech-domain'}) {&positionByTechDomain($new)}
+ }
+ &setHref($new,$contents);
+ print STDERR "$warning: Adding found $tag $id from $contents\n";
+ delete $replacing{$tag}->{$fullid};
+ }
+ # newline after each new tag so output's not ugly
+ if($new->getNextSibling)
+ {
+ $node->insertBefore($doc->createTextNode ("\n"),$new->getNextSibling);
+ }
+ else
+ {
+ $node->appendChild($doc->createTextNode ("\n"));
+ }
+ delete $newContainer{$ppath};
+ }
+
+
+sub getNamespacePrefix
+ {
+ my $node = shift;
+ my $ns = shift;
+ my $root = $node->getOwnerDocument->getDocumentElement;
+ my $idns = $root->getAttribute("id-namespace");
+ if($idns && $idns eq $ns) {return}
+ if(!$idns && $defaultns eq $ns) {return}
+ foreach my $a (keys %{$root->getAttributes})
+ {
+ my $pre = $a;
+ if($pre=~s/^xmlns://)
+ {
+ if($node->getAttribute ($a) eq $ns) {return $pre}
+ }
+ }
+ die "ERROR: no namespace prefix defined for $ns";
+ }
+
+
+sub resolvePath
+ {
+ # return full path to 2nd arg relative to first (path or absolute URI)
+ my $base = shift;
+ my $path = shift;
+ if($path=~m,^/,) {return $path } # path is absolute, but has no drive. Let OS deal with it.
+ if($path=~s,^file:///([a-zA-Z]:/),$1,) {return $path } # file URI with drive letter
+ if($path=~m,^file://,) {return $path } # file URI with no drive letter (unit-style). Just pass on as is with leading / and let OS deal with it
+ if($path=~m,^[a-z0-9][a-z0-9]+:,i) {return $path } # absolute URI -- no idea how to handle, so just return
+ return &abspath(File::Basename::dirname($base)."/$path");
+ }
+
+
+sub fixHref {
+ my $node = shift;
+ my $base = shift;
+ my $link= $node->getAttribute('href');
+ if($link=~/^(ftp|http)s:\/\//) {return} # remote link, do nothing
+ my $path = &resolvePath($base,$link);
+ if(!-e $path)
+ { # no such file, delete
+ my $tag =$node->getTagName;
+ my $id = $node->getAttribute('id');
+ print STDERR "$warning: $tag $id not found at $link\n";
+ $node->getParentNode->removeChild($node);
+ return;
+ }
+ if($output eq '')
+ {
+ $path=~s,^/?,file:///,;
+ $node->setAttribute('href',$path); # replace with absolute URI
+ return;
+ }
+ $node->setAttribute('href',&normpath($modpath.$link)); # make relative path to output file
+ }
+
+
+sub setHref {
+ my $node = shift;
+ my $file = shift;
+ if($output eq '')
+ {
+ $path = &abspath($file);
+ $path=~s,^/?,file:///,;
+ $node->setAttribute('href',$path); # replace with absolute URI
+ }
+ else
+ {
+ $node->setAttribute('href',&relativeTo(&abspath($output),$file,'file'));
+ }
+}
+
+
+sub relativeTo {
+ if($_[0] eq '') {return &abspath($_[1])}
+ my @outfile = split(/[\\\/]/,lc(shift));
+ my @infile = split(/[\\\/]/,lc(shift));
+ my $asdir = shift ne 'file';
+ while($outfile[0] eq $infile[0])
+ {
+ shift(@outfile);
+ shift(@infile);
+ }
+ $modpath = '../' x (scalar(@outfile) - 1);
+ if($asdir) {
+ if(scalar @infile > 1) {$modpath .= join('/',@infile[0..$#infile - 1]).'/'}
+ } else {$modpath .= join('/',@infile)}
+ return $modpath;
+}
+
+sub positionByTechDomain
+ {
+ my $node=shift;
+ my $td = $node->getAttribute('tech-domain');
+ my %before;
+ foreach my $t (@tdOrder)
+ {
+ $before{$t}=1;
+ if($t eq $td) {last}
+ }
+ my $prev = $node->getPreviousSibling;
+ foreach my $child (reverse @{$node->getParentNode->getChildNodes})
+ {
+ if($child->getNodeType==1 && $child->getTagName eq 'package' && $child!=$node)
+ {
+ if($before{$child->getAttribute('tech-domain')})
+ {
+ my $next = $child->getNextSibling;
+ while($next && $next->getNodeType!=1) {$next = $next->getNextSibling}
+ if($next) {
+ $node->getParentNode->insertBefore ($node,$next);
+ }
+ last;
+ }
+ }
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/sysdefdowngrade.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,425 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Downgrade a 3.x system definition into the 2.0.1 syntax
+-->
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:param name="Path">os/deviceplatformrelease/foundation_system/system_model</xsl:param>
+ <!-- $Path is the location of the root system definition XML file. Must not end in /
+ This is used to compute the absolute paths the 2.0 syntax needs-->
+ <xsl:param name="Root"/> <!-- space separated list of root variables in the form "VAR1=value1 VAR=value2" -->
+ <xsl:variable name="root" select="concat(' ',$Root,' ')"/> <!-- sort of hack to allow absolute paths in downgraded output -->
+ <xsl:variable name="srcroot" select="substring-before(substring-after($root,' SRCROOT='),' ')"/> <!-- the default path prefix -->
+
+<xsl:template match="/*">
+ <xsl:message terminate="yes">ERROR: Cannot process this document</xsl:message>
+</xsl:template>
+
+<!-- can only handle 3.0.0 to 2.0.1 transforms
+ Assumes only packages are using href
+ -->
+<xsl:template match="/SystemDefinition[@schema='3.0.0']">
+ <!-- process root system definition or package definition-->
+ <xsl:call-template name="DTD"/> <!-- insert 2.0.01 DTD -->
+ <SystemDefinition name="{*/@name}" schema="2.0.1">
+ <xsl:apply-templates select="*|comment()"/>
+ </SystemDefinition>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition[@schema='3.0.0' and systemModel]">
+ <xsl:call-template name="DTD"/> <!-- insert 2.0.01 DTD -->
+ <SystemDefinition name="{systemModel/@name}" schema="2.0.1">
+ <xsl:apply-templates select="*|comment()"/>
+ </SystemDefinition>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition/package[@href]" priority="2">
+ <xsl:message terminate="yes">ERROR: Package definition (<xsl:value-of select="@id"/>) cannot link another package</xsl:message>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition/package" priority="1">
+ <!-- process package definition file-->
+ <systemModel>
+ <layer name="anonymous"> <!-- fake layer -->
+ <block>
+ <xsl:apply-templates mode="copy" select="@id|@name|@span|@level|@levels"/><!-- valid attribuites for 2.0 -->
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="concat($Path,'/')"/> <!-- need to keep tack of where the current document is -->
+ </xsl:apply-templates>
+ </block>
+ </layer>
+ </systemModel>
+</xsl:template>
+
+
+
+<xsl:template match="/"><xsl:apply-templates select="*"/></xsl:template>
+<xsl:template match="@*|comment()"><xsl:copy-of select="."/></xsl:template>
+ <!-- comments are copied verbatim. Attribtues are copied by default -->
+
+<xsl:template match="systemModel">
+ <systemModel>
+ <xsl:apply-templates select="*|comment()"> <!-- no attributes -->
+ <xsl:with-param name="path" select="$Path"/> <!-- need to keep tack of where the current document is -->
+ </xsl:apply-templates>
+ </systemModel>
+</xsl:template>
+
+<xsl:template mode="copy" match="@*">
+ <xsl:copy-of select="."/>
+</xsl:template>
+
+<xsl:template mode="copy" match="@id"> <!-- id in 3.0 is name in 2.0 -->
+ <xsl:attribute name="name"><xsl:value-of select="."/></xsl:attribute>
+</xsl:template>
+
+<xsl:template mode="copy" match="@name"> <!-- name in 3.0 is long-name in 2.0.1 -->
+ <xsl:if test=".!=../@id"> <!-- don't bother if it will be the same as name -->
+ <xsl:attribute name="long-name"><xsl:value-of select="."/></xsl:attribute>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="layer"><xsl:param name="path"/>
+ <layer>
+ <xsl:apply-templates mode="copy" select="@id|@name|@span|@levels"/> <!-- valid attribuites for 2.0 -->
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+ </layer>
+</xsl:template>
+
+<xsl:template match="layer/package"><!-- translates to block -->
+ <xsl:param name="path"/>
+ <block>
+ <xsl:apply-templates mode="copy" select="@id|@name|@span|@level|@levels"/><!-- valid attribuites for 2.0 -->
+ <xsl:choose>
+ <xsl:when test="@href">
+ <xsl:variable name="this" select="."/>
+ <xsl:variable name="prefixmap" select="ancestor::SystemDefinition/*/meta[@rel='link-mapping']/map-prefix[starts-with(current()/@href,@link)]"/>
+ <xsl:for-each select="document(@href,.)/SystemDefinition/*">
+ <xsl:variable name="my-id"><xsl:apply-templates mode="normalize-id" select="@id"/></xsl:variable>
+ <xsl:variable name="other-id"><xsl:apply-templates mode="normalize-id" select="$this/@id"/></xsl:variable>
+ <xsl:if test="$my-id != $other-id">
+ <xsl:message terminate="yes">ERROR: Package IDs do not match: <xsl:value-of select="$my-id"/> vs <xsl:value-of select="$other-id"/></xsl:message>
+ </xsl:if>
+ <xsl:if test="@name and @name!=@id and not($this/@name and $this/@name=$this/@id)">
+ <!-- set long-name only if name is different from the id and not set in child doc -->
+ <xsl:attribute name="long-name"><xsl:value-of select="@name"/></xsl:attribute>
+ </xsl:if>
+ <xsl:for-each select="@span|@levels|@level">
+ <!-- copy only if not set in child doc -->
+ <xsl:if test="not(this/@*[name()=name(current())])">
+ <xsl:copy-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path">
+ <xsl:choose>
+ <xsl:when test="$prefixmap">
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path">
+ <xsl:apply-templates select="$prefixmap/@to"/>
+ <xsl:value-of select="substring-after($this/@href,$prefixmap/@link)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="starts-with($this/@href,'/')"> <!-- absolute path -->
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path" select="$this/@href"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($this/@href,'://')"> <!-- generic URI -->
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path" select="substring-after($this/@href,'://')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path" select="concat($path,'/',$this/@href)"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </block>
+</xsl:template>
+
+<xsl:template match="package/package"> <!-- translates to subblock --><xsl:param name="path"/>
+ <subblock>
+ <xsl:apply-templates mode="copy" select="@id|@name"/>
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+ </subblock>
+</xsl:template>
+
+<xsl:template match="package/package/pacakge"> <!-- cannot nest this deep --><xsl:param name="path"/>
+ <xsl:message>WARNING: Excessive nesting of packages: Ignoring <xsl:value-of select="@id"/></xsl:message>
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+
+<xsl:template match="collection"><xsl:param name="path"/>
+ <collection>
+ <xsl:apply-templates mode="copy" select="@id|@name|@level"/>
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+ </collection>
+</xsl:template>
+
+
+<xsl:template match="component"><xsl:param name="path"/>
+ <component>
+ <xsl:apply-templates mode="copy" select="@id|@name|@deprecated|@introduced|@filter|@purpose"/>
+ <xsl:if test="contains(concat(' ',@class,' '),' plugin ')">
+ <xsl:attribute name="plugin">Y</xsl:attribute>
+ </xsl:if>
+ <xsl:call-template name="class">
+ <xsl:with-param name="remove">plugin</xsl:with-param>
+ <xsl:with-param name="add">
+ <xsl:if test="not(*) and comment()">placeholder</xsl:if>
+ <xsl:if test="@target='desktop'"> PC</xsl:if>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:apply-templates select="*|comment()">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+ </component>
+</xsl:template>
+
+<xsl:template match="unit[@base and not(@mrp or @bldFile)]"/>
+
+<xsl:template match="unit"><xsl:param name="path"/>
+ <unit>
+ <xsl:apply-templates select="@mrp|@bldFile|@late">
+ <xsl:with-param name="path" select="$path"/>
+ </xsl:apply-templates>
+ <xsl:copy-of select="@filter|@root[not(contains($root,concat(' ',.,'=')))]|@version|@prebuilt|@priority"/>
+ </unit>
+</xsl:template>
+
+<xsl:template match="unit/@late"> <!-- 2.0 uses Y/N, 3.0 uses yes/no -->
+ <xsl:attribute name="{name()}">
+ <xsl:choose>
+ <xsl:when test=".='yes'">Y</xsl:when>
+ <xsl:when test=".='no'">N</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+</xsl:template>
+
+<xsl:template match="@mrp|@bldFile"><xsl:param name="path"/>
+ <xsl:attribute name="{name()}">
+ <xsl:choose>
+ <xsl:when test="../@root">
+ <xsl:variable name="pre" select="substring-before(substring-after($root,concat(' ',../@root,'=')),' ')"/>
+ <xsl:value-of select="$pre"/>
+ <xsl:if test="$pre!='' and $pre!='/'">/</xsl:if>
+ </xsl:when>
+ <xsl:when test="$srcroot='/'"> <!-- treat all paths as absolute -->
+ <xsl:value-of select="$srcroot"/>
+ </xsl:when>
+ <xsl:when test="$srcroot!=''">
+ <xsl:value-of select="concat($srcroot,'/')"/>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="starts-with(.,'/')"> <!-- keep absolute paths verbatim (barring the leading / ) -->
+ <xsl:value-of select="substring-after(.,'/')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path">
+ <xsl:call-template name="before">
+ <xsl:with-param name="text" select="$path"/>
+ </xsl:call-template>
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+</xsl:template>
+
+<xsl:template match="meta"/> <!-- strip all meta tags -->
+
+<xsl:template match="meta[info/@contract]"> <!-- except contract -->
+ <xsl:copy-of select="info/@contract"/>
+</xsl:template>
+
+
+<xsl:template match="meta[@rel='link-mapping']/map-prefix/@to">
+ <xsl:choose>
+ <xsl:when test="starts-with(.,'/')"><xsl:value-of select="substring(.,2)"/></xsl:when> <!-- absolute paths in 3.0 are relative in 2.0 -->
+ <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="@id" mode="normalize-id">
+ <xsl:choose>
+ <xsl:when test="contains(@id,':')"><xsl:value-of select="substring-after(@id,':')"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="@id"/></xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="class"><xsl:param name="remove"/><xsl:param name="add"/>
+<!-- returns the value of the class attribute with the space-separated list of names in $remove taken out and those in $add added on (does not check for duplicates) -->
+ <xsl:param name="class" select="normalize-space(@class)"/>
+ <xsl:variable name="r">
+ <xsl:text> </xsl:text>
+ <xsl:choose>
+ <xsl:when test="contains($remove,' ')"><xsl:value-of select="substring-before($remove,' ')"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$remove"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> </xsl:text>
+ </xsl:variable>
+ <xsl:variable name="c">
+ <xsl:choose>
+ <xsl:when test="contains(concat(' ',$class,' '),$r)">
+ <xsl:value-of select="substring-before(concat(' ',$class,' '),$r)"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="substring-after(concat(' ',$class,' '),$r)"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$class"/></xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="normalize-space($add)!=''"><xsl:value-of select="concat(' ',normalize-space($add))"/></xsl:if>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="contains($remove,' ')">
+ <xsl:call-template name="class">
+ <xsl:with-param name="remove" select="substring-after($remove,' ')"/>
+ <xsl:with-param name="class" select="$c"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="normalize-space($c)!=''">
+ <xsl:attribute name="class">
+ <xsl:value-of select="normalize-space($c)"/>
+ </xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="normpath"><xsl:param name="path"/>
+<!-- normalize out any ".." in the path in $path -->
+<xsl:choose>
+ <xsl:when test="contains($path,'/../')">
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path">
+ <xsl:call-template name="before">
+ <xsl:with-param name="text" select="substring-before($path,'/../')"/>
+ </xsl:call-template>
+ <xsl:value-of select="substring-after($path,'/../')"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$path"/></xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+
+<!-- return all text before the last / -->
+<xsl:template name="before"><xsl:param name="text"/>
+<xsl:if test="contains($text,'/')">
+ <xsl:value-of select="substring-before($text,'/')"/>/<xsl:call-template name="before"><xsl:with-param name="text" select="substring-after($text,'/')"/></xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template name="DTD">
+<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE SystemDefinition [
+<!ELEMENT SystemDefinition ( systemModel )>
+<!ATTLIST SystemDefinition
+ name CDATA #REQUIRED
+ schema CDATA #REQUIRED
+>
+<!-- all paths are relative to the environment variable specified by the root attribute, or SOURCEROOT if not. -->
+
+<!-- System Model Section of DTD -->
+<!ELEMENT systemModel (layer+)>
+
+<!ELEMENT layer (block* | collection*)*>
+<!-- Kernel Services, Base Services, OS Services, Etc -->
+<!ATTLIST layer
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ levels NMTOKENS #IMPLIED
+ span CDATA #IMPLIED
+>
+
+<!ELEMENT block (subblock* | collection*)*>
+ <!-- Generic OS services, Comms Services, etc -->
+<!ATTLIST block
+ levels NMTOKENS #IMPLIED
+ span CDATA #IMPLIED
+ level NMTOKEN #IMPLIED
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+>
+
+<!ELEMENT subblock (collection)*>
+<!-- Cellular Baseband Services, Networking Services, etc -->
+<!ATTLIST subblock
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+>
+
+<!ELEMENT collection (component)*>
+<!-- Screen Driver, Content Handling, etc -->
+<!ATTLIST collection
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ level NMTOKEN #IMPLIED
+>
+
+<!ELEMENT component (unit)*>
+<!-- contains units or is a package or prebuilt -->
+<!ATTLIST component
+ name CDATA #REQUIRED
+ long-name CDATA #IMPLIED
+ deprecated CDATA #IMPLIED
+ introduced CDATA #IMPLIED
+ contract CDATA #IMPLIED
+ plugin (Y|N) "N"
+ filter CDATA #IMPLIED
+ class NMTOKENS #IMPLIED
+ supports CDATA #IMPLIED
+ purpose ( optional | mandatory | development ) "optional"
+>
+
+<!ELEMENT unit EMPTY >
+<!-- must be buildable (bld.inf) -->
+<!-- bldFile may someday be removed in favour of mrp -->
+<!ATTLIST unit
+ mrp CDATA #IMPLIED
+ filter CDATA #IMPLIED
+ bldFile CDATA #IMPLIED
+ root CDATA #IMPLIED
+ version NMTOKEN #IMPLIED
+ prebuilt NMTOKEN #IMPLIED
+ late (Y|N) #IMPLIED
+ priority CDATA #IMPLIED
+>
+]>
+]]></xsl:text>
+</xsl:template>
+</xsl:stylesheet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/validate/checklinks.pl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,108 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Script to validate the unit links in a system definition or package definition XML file
+
+use strict;
+
+if (! scalar @ARGV) {&help()}
+
+
+my $debug = 0;
+my $skipfilter; # skip anything with a named filter
+my $xslt = "../../../buildtools/bldsystemtools/buildsystemtools/joinsysdef.xsl";
+my $xalan = "../../../buildtools/devlib/devlibhelp/tools/doc_tree/lib/apache/xalan.jar";
+my $sysdef = shift;
+while($sysdef=~/^-/) { #arguments
+ if($sysdef eq '-nofilter') {$skipfilter = shift}
+ elsif($sysdef eq '-v') {$debug = 1}
+ else { &help("Invalid command line option $sysdef")}
+ $sysdef = shift;
+}
+my $dir = $sysdef;
+$dir =~ s,[^\\/]+$,,;
+my $root="../../../..";
+ my $full;
+
+if($sysdef=~/system_definition\.xml/) { # if running on a sysdef, ensure it's joined before continuing
+ ($full = `java -jar $dir$xalan -in $sysdef -xsl $dir$xslt`) || die "bad XML syntax";
+}else { # assume any other file has no hrefs to include (valid by convention)
+ $root='';
+ open S, $sysdef;
+ $full=join('',<S>);
+ close S;
+}
+$full=~s/<!--.*?-->//sg; # remove all comments;
+my $count=1;
+
+my $filter = '';
+foreach (split(/</,$full)) { # loop through all elements
+ my $found = 0;
+ if(/^component/) { # save the current filter so we know if we need to skip the named filter
+ $filter='';
+ if(/filter="([^"]+)"/) {$filter=$1}
+ }
+ elsif(s/^unit//) {
+ my $f=",$filter,"; # commas are the separators - safe to have extra ones for testing
+ if(/filter="([^"]+)"/) {$f.=",$1,"}
+ if($skipfilter ne '' && $f=~/,$filter,/) {next} # don't test anything with s60 filter
+ if(/\smrp="(.*?)"/) {
+ my $file = &fileLocation($1);
+ if($debug) {print "MRP ",-s $file," $file\n"} # debug code
+ if(!(-s $file)){
+ print STDERR "$count: Cannot find MRP file $file\n";
+ $found=1;
+ }
+ }
+ if(/\sbldFile="(.*?)"/) {
+ my $file = &fileLocation("$1/bld.inf");
+ if($debug) {print "Bld ",-s $file ," $file\n"} # debug code
+ if(!(-s $file) ){
+ print STDERR "$count: Cannot find bld.inf file $file\n";
+ $found=1;
+ }
+ }
+ if(/\sbase="(.*?)"/) {
+ my $file = &fileLocation($1);
+ if($debug) {print "Base $file\n"} # debug code
+ if(!(-d $file) ){
+ print STDERR "$count: Cannot find base dir $file\n";
+ $found=1;
+ }
+ }
+ }
+ $count+=$found;
+}
+
+exit $count;
+
+sub fileLocation {
+ my $file = "$dir$root$_[0]";
+ $file=~tr/\//\\/;
+ while($file=~s/\\[^\\.]+\\\.\.\\/\\/){}
+ return $file;
+}
+sub help {
+ print "$0: ",($_[0] eq '' ? "syntax" : $_[0]);
+ print "\nSyntax: [-v] [-nofilter filter] system_definition.xml
+Validate the unit links in a system definition or package definition XML
+file. This only prints errors in the files. If it exits silently, the links
+are all valid.
+ Call with -nos60 filter to skip checking presence of fitler=\"s60\" units
+ Requires system definition files to be in the standard location
+ in deviceplatformrelease,
+ and the presence of joinsysdef.xsl and xalan.jar in their expected
+ locations.
+ Package definition files can be anywhere.";
+exit 1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/validate/modelcheck.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,71 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Validate a system definition file or files and output results in HTML
+-->
+ <xsl:output method="html"/>
+ <xsl:include href="test-model.xsl"/>
+<xsl:template match="/model">
+ <html><head>
+ <title>Cross-Checking System Model</title>
+ <style>p {margin: 0px; padding: 0px}
+ p.warn span {color: blue}
+ p.note span {color: green}
+ p.err span {font-weight: bold}
+ p.err {color: red; background: yellow}
+ p.note {font-size: 90%}
+ <xsl:if test="contains(concat(' ',normalize-space(/model/@supress-errors),' '),' note ')">
+ p.note {display: none}
+ </xsl:if>
+ <xsl:if test="contains(concat(' ',normalize-space(/model/@supress-errors),' '),' err ')">
+ p.err {display: none}
+ </xsl:if>
+ <xsl:if test="contains(concat(' ',normalize-space(/model/@supress-errors),' '),' warn ')">
+ p.warn {display: none}
+ </xsl:if>
+ </style>
+ </head><body>
+ <xsl:apply-templates select="." mode="check"/>
+ </body></html>
+</xsl:template>
+
+
+<xsl:template name="Section"><xsl:param name="text"/><xsl:param name="sub"/>
+<h2><xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"><xsl:text> </xsl:text> <small>(<xsl:value-of select="$sub"/>)</small></xsl:if></h2>
+</xsl:template>
+
+<xsl:template name="Note"><xsl:param name="text"/><xsl:param name="sub"/>
+<p class="note">
+ <span>Note:</span>
+ <xsl:text> </xsl:text>
+ <xsl:copy-of select="$text"/>
+<xsl:if test="$sub!=''"><xsl:text> </xsl:text> <small>(<xsl:value-of select="$sub"/>)</small></xsl:if></p>
+</xsl:template>
+
+<xsl:template name="Warning"><xsl:param name="text"/><xsl:param name="sub"/>
+<p class="warn">
+ <span>Warning:</span>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"><xsl:text> </xsl:text> <small>(<xsl:value-of select="$sub"/>)</small></xsl:if></p>
+</xsl:template>
+
+<xsl:template name="Error"><xsl:param name="text"/><xsl:param name="sub"/>
+<p class="err">
+ <span>Error:</span>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"><xsl:text> </xsl:text> <small>(<xsl:value-of select="$sub"/>)</small></xsl:if></p>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/validate/test-model.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,490 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Module containing the validation logic for system definition 3.0.0 syntax
+-->
+ <xsl:key name="named" match="*[ancestor::systemModel]" use="@name"/>
+ <xsl:param name="Filename"/>
+ <xsl:variable name="info" select="document(/model//info[@type='extra']/@href,/model)//c"/>
+
+ <xsl:variable name="all-ids">
+ <xsl:apply-templates select="document(/model/sysdef/@href)| SystemDefinition" mode="ids"/>
+ </xsl:variable>
+
+
+<xsl:template match="/model" priority="-1">
+ <xsl:apply-templates select="." mode="check"/>
+</xsl:template>
+
+<xsl:template match="/model" mode="check">
+ <xsl:for-each select="sysdef">
+ <xsl:apply-templates select="document (@href,. )/*">
+ <xsl:with-param name="filename">
+ <xsl:choose>
+ <xsl:when test="starts-with(current()/@href,current()/@rootpath)">
+ <xsl:value-of select="substring-after(current()/@href,current()/@rootpath)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@href"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:apply-templates>
+ </xsl:for-each>
+
+
+
+<xsl:apply-templates mode="x-check" select="document (//info[@type='vp']/@href)/*">
+ <xsl:with-param name="sysdef" select="document (sysdef/@href)/*"/>
+</xsl:apply-templates>
+
+<xsl:apply-templates mode="x-check" select="document (//info[@type='build']/@href)/*">
+ <xsl:with-param name="sysdef" select="document (sysdef/@href)/*"/>
+</xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition[@schema='3.0.0']" mode="ids">
+ <xsl:for-each select="//*[@id and not(@href)]"><xsl:value-of select="concat(' ',@id,' ')"/></xsl:for-each>
+ <xsl:apply-templates select="document(//layer/@href | //package/@href | //collection/@href | //component/@href,.)/*" mode="ids"/>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition[@schema='3.0.0' and systemModel]" priority="2">
+ <xsl:param name="filename" select="$Filename"/>
+<xsl:call-template name="Section">
+ <xsl:with-param name="text">System Definition: <xsl:value-of select="*/@name"/></xsl:with-param>
+ <xsl:with-param name="sub"><xsl:value-of select="(string-length($all-ids) - string-length(translate($all-ids,' ',''))) div 2 "/> items</xsl:with-param>
+</xsl:call-template>
+ <xsl:apply-templates select="*">
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition[@schema='3.0.0'] | systemModel">
+ <xsl:param name="filename" select="$Filename"/>
+
+<xsl:if test="//unit">
+<xsl:call-template name="Section">
+ <xsl:with-param name="text"><xsl:value-of select="translate(substring(name(*),1,1),'clp','CLP')"/><xsl:value-of select="substring(name(*),2)"/> Definition: <xsl:value-of select="*/@name"/></xsl:with-param>
+ <xsl:with-param name="sub"><xsl:value-of select="count(//unit)"/> unit<xsl:if test="count(//unit)!=1">s</xsl:if></xsl:with-param>
+</xsl:call-template>
+</xsl:if>
+<xsl:if test="self::systemModel and not(@name)">
+ <xsl:call-template name="Error"><xsl:with-param name="text">systemModel element should have a name</xsl:with-param></xsl:call-template>
+</xsl:if>
+ <xsl:apply-templates select="*">
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+
+<xsl:template match="@*" mode="valid">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Attribute <xsl:value-of select="name()"/>="<xsl:value-of select="."/>" is not valid for <xsl:value-of select="name(..)"/></xsl:with-param></xsl:call-template>
+</xsl:template>
+
+<xsl:template match="@before|@id|package/@span|collection/@level|package/@level|package/@levels|layer/@levels" mode="valid"/> <!-- really should check syntax -->
+
+<xsl:template match="@name|@href|@filter" mode="valid"/>
+
+<xsl:template match="component/@introduced|component/@deprecated" mode="valid"/>
+
+
+<xsl:template name="validate-class">
+ <ok>plugin</ok>
+ <ok>doc</ok>
+ <ok>tool</ok>
+ <ok>config</ok>
+ <ok>api</ok>
+ <w d="deprecated">test</w>
+</xsl:template>
+
+<xsl:template name="validate-purpose">
+ <ok>mandatory</ok>
+ <ok>optional</ok>
+ <ok>development</ok>
+</xsl:template>
+<xsl:template name="validate-target">
+ <ok>other</ok>
+ <ok>desktop</ok>
+ <ok>device</ok>
+</xsl:template>
+
+
+<xsl:template name="validate-tech-domain">
+ <ok>lo</ok>
+ <ok>hb</ok>
+ <ok>mm</ok>
+ <ok>ma</ok>
+ <ok>pr</ok>
+ <ok>vc</ok>
+ <ok>se</ok>
+ <ok>ui</ok>
+ <ok>dc</ok>
+ <ok>de</ok>
+ <ok>dm</ok>
+ <ok>rt</ok>
+ <ok>to</ok>
+ <w d="Non-standard">ocp</w>
+</xsl:template>
+
+<xsl:template match="component/@class" mode="valid">
+ <xsl:call-template name="checklist">
+ <xsl:with-param name="list" select="normalize-space(.)"/>
+ <xsl:with-param name="values" select="document('')/*/xsl:template[@name=concat('validate-',name(current()))]/*"/>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="checklist">
+ <xsl:param name="list" select="."/><xsl:param name="values"/><xsl:param name="sep" select="' '"/>
+ <xsl:variable name="item">
+ <xsl:choose>
+ <xsl:when test="contains($list,$sep)"><xsl:value-of select="substring-before($list,$sep)"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$list"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="v" select="$values[.=$item]"/>
+ <xsl:choose>
+ <xsl:when test="not($v)">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Illegal <xsl:value-of select="name()"/> value <xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="name($v)='ok'"/>
+ <xsl:when test="name($v)='w'">
+ <xsl:call-template name="Warning"><xsl:with-param name="text"><xsl:value-of select="$v/@d"/> value in <xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:if test="contains($list,$sep)">
+ <xsl:call-template name="checklist">
+ <xsl:with-param name="list" select="substring-after($list,$sep)"/>
+ <xsl:with-param name="values" select="$values"/>
+ <xsl:with-param name="sep" select="$sep"/>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+
+<xsl:template match="package/@tech-domain|component/@purpose|component/@target" mode="valid">
+ <xsl:variable name="v" select="document('')/*/xsl:template[@name=concat('validate-',name(current()))]/*[.=current()]"/>
+ <xsl:choose>
+ <xsl:when test="not($v)">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Illegal <xsl:value-of select="name()"/> value <xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="name($v)='ok'"/>
+ <xsl:when test="name($v)='w'">
+ <xsl:call-template name="Warning"><xsl:with-param name="text"><xsl:value-of select="$v/@d"/> value in <xsl:value-of select="name()"/>="<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+
+
+
+
+<xsl:template match="*" priority="-2">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Element "<xsl:value-of select="name()"/>" is not valid in the context of "<xsl:value-of select="name(..)"/>"</xsl:with-param></xsl:call-template>
+</xsl:template>
+
+<xsl:template match="component[not(parent::collection)] | collection[not(parent::package)] | package[not(parent::package or parent::layer or (parent::SystemDefinition and count(../*)=1))] | layer[not(parent::systemModel)] " priority="3">
+ <xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" has invalid parent <xsl:value-of select="name(..)"/> "<xsl:value-of select="../@id"/>"</xsl:with-param></xsl:call-template>
+</xsl:template>
+
+<xsl:template match="layer | package | collection | component">
+ <xsl:param name="filename"/>
+
+<xsl:apply-templates select="@*" mode="valid"/>
+<xsl:apply-templates select="@id"/>
+<xsl:if test="self::component">
+ <xsl:choose>
+ <xsl:when test="count(*[not(@version)]) > 1 and @filter='s60'">
+ <xsl:call-template name="Warning"><xsl:with-param name="text">S60 Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(*)"/> children.</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="count(*[not(@version)]) > 1">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(*)"/> children.</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="unit"/>
+ <xsl:when test="contains(comment(),'PLACEHOLDER=')"/>
+ <xsl:when test="comment()">
+ <xsl:call-template name="Note"><xsl:with-param name="text">Component "<xsl:value-of select="@name"/>" is empty.</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not(comment())">
+ <xsl:call-template name="Warning"><xsl:with-param name="text">Component "<xsl:value-of select="@name"/>" is empty and has no comment</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+</xsl:if>
+<xsl:if test="@href">
+ <xsl:variable name="child" select="document(@href,.)/SystemDefinition"/>
+ <xsl:if test="@id!=$child/@id">
+ <xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" must match ID in linked file "<xsl:value-of select="@href"/>"</xsl:with-param></xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$child/@href">
+ <xsl:call-template name="Error"><xsl:with-param name="text">linked <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" cannot be a link</xsl:with-param></xsl:call-template>
+ </xsl:if>
+ <xsl:for-each select="@*[name()!='id']">
+ <xsl:if test="$child/@*[name()=name(current())]">
+ <xsl:call-template name="Warning"><xsl:with-param name="text">linked <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" has duplicate attribute to linking document. Duplicate ignored.</xsl:with-param></xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:if test="*">
+ <xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" cannot have both link and content. Content ignored.</xsl:with-param></xsl:call-template>
+ </xsl:if>
+</xsl:if>
+<xsl:if test="@href and name()!=name(document(@href,.)/SystemDefinition/*)">
+ <xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" must match item in linked file "<xsl:value-of select="@href"/>"</xsl:with-param></xsl:call-template>
+</xsl:if>
+<xsl:if test="not(@href)">
+ <xsl:apply-templates select="*">
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+</xsl:if>
+<xsl:if test="@href">
+ <xsl:apply-templates select="document(@href,.)/*">
+ <xsl:with-param name="filename">
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path">
+ <xsl:if test="not(starts-with(current()/@href,'/'))">
+ <xsl:call-template name="before">
+ <xsl:with-param name="text" select="$filename"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:value-of select="current()/@href"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:apply-templates>
+</xsl:if>
+</xsl:template>
+
+
+<xsl:template match="unit"> <xsl:param name="filename"/>
+ <xsl:apply-templates select="@mrp|@bldFile">
+ <xsl:with-param name="filename" select="$filename"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+
+<xsl:template match="@id" mode="path">
+ <xsl:choose>
+ <xsl:when test="contains(.,':')"><xsl:value-of select="substring-after(.,':')"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="@id">
+<xsl:if test="contains(concat(' ',substring-after($all-ids,concat(' ',.,' '))),concat(' ',.,' '))">
+ <xsl:call-template name="Warning"><xsl:with-param name="text">Duplicate ID: <xsl:value-of select="name(..)"/> "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+</xsl:if>
+
+<xsl:if test="contains(.,':') and not(ancestor::*/namespace::*[name()=substring-before(current(),':')])">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Undefined namespace for ID "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+</xsl:if>
+
+</xsl:template>
+
+
+<xsl:template match="@bldFile|@mrp"><xsl:param name="filename"/>
+
+ <xsl:variable name="fullpath"><xsl:call-template name="normpath">
+ <xsl:with-param name="path">
+ <xsl:if test="not(starts-with(.,'/'))">
+ <xsl:call-template name="before">
+ <xsl:with-param name="text" select="$filename"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="path">
+ <xsl:choose>
+ <xsl:when test="not(contains($filename,':'))">/<xsl:for-each select="ancestor::*/@id"><xsl:apply-templates mode="path" select="."/>/</xsl:for-each></xsl:when>
+ <xsl:otherwise><xsl:for-each select="../../../@id|../../@id"><xsl:apply-templates mode="path" select="."/>/</xsl:for-each></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="segment">
+ <xsl:choose>
+ <xsl:when test="ancestor::layer">
+ <xsl:value-of select="concat($fullpath,'/')"/>
+ </xsl:when>
+ <xsl:when test="ancestor::package">
+ <xsl:value-of select="concat('/',substring-after(substring-after($fullpath,'/'),'/'),'/')"/>
+ </xsl:when>
+ <xsl:when test="ancestor::collection">
+ <xsl:value-of select="concat('/',substring-after(substring-after(substring-after($fullpath,'/'),'/'),'/'),'/')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('/',substring-after(substring-after(substring-after(substring-after($fullpath,'/'),'/'),'/'),'/'),'/')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+<xsl:choose>
+ <xsl:when test="contains($filename,':')">
+ <xsl:choose>
+ <xsl:when test="not(starts-with(.,$path) or concat(.,'/')=$path)">
+ <xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -> <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="substring-before(substring($segment,2),'/') != substring-before(substring($path,2),'/') and (ancestor::SystemDefinition/@id-namespace!='http://www.symbian.org/system-definition' and not(contains(../../@id,':')))">
+ <xsl:call-template name="Warning"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -> <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="substring-before(substring($segment,2),'/') != substring-before(substring($path,2),'/')">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -> <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not(starts-with($segment,$path))">
+ <xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -> <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:otherwise>
+</xsl:choose>
+<xsl:if test="substring(.,string-length(.))='/'">
+ <xsl:call-template name="Warning"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" should not end in /</xsl:with-param></xsl:call-template>
+</xsl:if>
+<xsl:if test="contains(.,'\')">
+ <xsl:call-template name="Error"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" must use only forward slashes</xsl:with-param></xsl:call-template>
+</xsl:if>
+</xsl:template>
+
+
+<xsl:template match="SystemDefinition" mode="check-matches">
+ <xsl:param name="which"/>
+ <xsl:param name="other"/>
+ <xsl:for-each select="//*[@mrp]">
+ <xsl:variable name="mrp" select="@mrp"/>
+ <xsl:if test="not($other//*[@mrp=$mrp])">
+ <xsl:call-template name="Error"><xsl:with-param name="text"><xsl:value-of select="$mrp"/> has no match in <xsl:value-of select="$which"/>.</xsl:with-param></xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="*" mode="value">
+ <xsl:call-template name="Error"><xsl:with-param name="text">
+ <xsl:value-of select="name()"/>:<xsl:for-each select="@*"><xsl:value-of select="concat(name(),'=',.)"/></xsl:for-each>
+ </xsl:with-param></xsl:call-template>
+</xsl:template>
+
+<xsl:template match="*" mode="compare"><xsl:param name="base"/>
+<xsl:variable name="n" select="@id"/>
+<xsl:variable name="tag" select="name()"/>
+<xsl:variable name="v"><xsl:apply-templates select="." mode="value"/></xsl:variable>
+<xsl:variable name="v2"><xsl:apply-templates mode="value" select="$base//*[name()=$tag and @id=$n]"/></xsl:variable>
+<xsl:if test="$v != $v2">
+ <xsl:call-template name="Error"><xsl:with-param name="text">
+ <xsl:value-of select="concat(name(),' ',@name)"/> not identical. [<xsl:value-of select="$v"/>|<xsl:value-of select="$v2"/>]</xsl:with-param></xsl:call-template>
+</xsl:if>
+</xsl:template>
+
+
+
+<xsl:template match="unit" mode="compare" priority="1"><xsl:param name="base"/>
+<xsl:variable name="n" select="concat(@version,':',@mrp,'.',@prebuilt)"/>
+<xsl:variable name="v"><xsl:apply-templates select="." mode="value"/></xsl:variable>
+<xsl:variable name="v2"><xsl:apply-templates mode="value" select="$base//unit[concat(@version,':',@mrp,'.',@prebuilt)=$n]"/></xsl:variable>
+<xsl:if test="$v != $v2">
+ <xsl:call-template name="Error"><xsl:with-param name="text">
+ <xsl:value-of select="concat('
',name(),' ',../@name,' v',@version)"/> not identical. [<xsl:value-of select="$v"/>|<xsl:value-of select="$v2"/>]</xsl:with-param></xsl:call-template>
+</xsl:if>
+</xsl:template>
+
+<xsl:template match="/variations/@module"> (<xsl:value-of select="."/>)</xsl:template>
+
+<xsl:template match="/variations" mode="x-check"><xsl:param name="sysdef"/>
+<xsl:call-template name="Section"><xsl:with-param name="text">vp cross-check <xsl:apply-templates select="@module"/></xsl:with-param></xsl:call-template>
+<xsl:for-each select="//component">
+ <xsl:variable name="found">
+ <xsl:apply-templates select="$sysdef" mode="lookfor">
+ <xsl:with-param name="id" select="@name"/>
+ <xsl:with-param name="version" select="@version"/>
+ </xsl:apply-templates>
+ </xsl:variable>
+ <xsl:if test="$found=''">
+ <xsl:call-template name="Error"><xsl:with-param name="text">VP component "<xsl:value-of select="@name"/>"<xsl:if test="@version"> v<xsl:value-of select="@version"/></xsl:if> not in SysDef</xsl:with-param></xsl:call-template>
+ </xsl:if>
+</xsl:for-each>
+</xsl:template>
+
+<xsl:template match="*" mode="lookfor"><xsl:param name="id"/><xsl:param name="version"/>
+ <xsl:choose>
+ <xsl:when test="string-length($version) and //component[@id=$id and unit[@version=$version]]">Found</xsl:when>
+ <xsl:when test="string-length($version)=0 and //*[@id=$id]">Found</xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="document(//layer/@href | //package/@href | //collection/@href | //component/@href,.)/*/*" mode="lookfor">
+ <xsl:with-param name="version" select="$version"/>
+ <xsl:with-param name="id" select="$id"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+
+<xsl:template match="SystemBuild" mode="x-check"><xsl:param name="sysdef"/>
+
+<xsl:call-template name="Section"><xsl:with-param name="text">System Build cross-check</xsl:with-param></xsl:call-template>
+<xsl:for-each select="//ref">
+ <xsl:variable name="found">
+ <xsl:apply-templates select="$sysdef" mode="lookfor">
+ <xsl:with-param name="id" select="current()/@item"/>
+ </xsl:apply-templates>
+</xsl:variable>
+ <xsl:if test="$found=''">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Build item "<xsl:value-of select="@item"/>" not in SysDef</xsl:with-param></xsl:call-template>
+</xsl:if>
+</xsl:for-each>
+
+<xsl:for-each select="//listRef">
+ <xsl:if test="not(//list[@name=current()/@list])">
+ <xsl:call-template name="Error"><xsl:with-param name="text">Build list "<xsl:value-of select="@name"/>" not defined</xsl:with-param></xsl:call-template>
+</xsl:if>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="my-release">
+ <xsl:variable name="n" select="@name"/>
+ <xsl:variable name="new" select="@introduced"/>
+ <xsl:variable name="end" select="@deprecated"/>
+ <xsl:choose>
+ <xsl:when test="$new!='' and $end!=''">(<xsl:value-of select="concat($new,' - ',$end)"/>)</xsl:when>
+ <xsl:when test="$new!='' ">(<xsl:value-of select="$new"/>)</xsl:when>
+ <xsl:when test="$end!=''">(? - <xsl:value-of select="$end"/>)</xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="normpath"><xsl:param name="path"/>
+<!-- normalize out any ".." in the path in $path -->
+<xsl:choose>
+ <xsl:when test="contains($path,'/../')">
+ <xsl:call-template name="normpath">
+ <xsl:with-param name="path">
+ <xsl:call-template name="before">
+ <xsl:with-param name="text" select="substring-before($path,'/../')"/>
+ </xsl:call-template>
+ <xsl:value-of select="substring-after($path,'/../')"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="$path"/></xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+
+<!-- return all text before the last / -->
+<xsl:template name="before"><xsl:param name="text"/>
+<xsl:if test="contains($text,'/')">
+ <xsl:value-of select="substring-before($text,'/')"/>/<xsl:call-template name="before"><xsl:with-param name="text" select="substring-after($text,'/')"/></xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysdeftools/validate/validate-sysdef.xsl Tue Apr 06 10:25:29 2010 +0100
@@ -0,0 +1,48 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ This component and the accompanying materials are made available
+ under the terms of the License "Eclipse Public License v1.0"
+ which accompanies this distribution, and is available
+ at the URL "http://www.eclipse.org/legal/epl-v10.html".
+
+ Initial Contributors:
+ Nokia Corporation - initial contribution.
+ Contributors:
+ Description:
+ Validate a system definition file/files and output results as plain text
+-->
+ <xsl:output method="text"/>
+ <xsl:include href="test-model.xsl"/>
+ <xsl:param name="level" select="3"/>
+
+<xsl:template name="Section"><xsl:param name="text"/><xsl:param name="sub"/>
+<xsl:text>

</xsl:text>
+<xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"> (<xsl:value-of select="$sub"/>)</xsl:if>
+</xsl:template>
+
+
+<xsl:template name="Note"><xsl:param name="text"/><xsl:param name="sub"/>
+<xsl:if test="$level >= 3">
+<xsl:text>
Note: </xsl:text>
+<xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"> (<xsl:value-of select="$sub"/>)</xsl:if>
+</xsl:if>
+</xsl:template>
+
+<xsl:template name="Warning"><xsl:param name="text"/><xsl:param name="sub"/>
+<xsl:if test="$level >= 2">
+<xsl:text>
Warning: </xsl:text>
+<xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"> (<xsl:value-of select="$sub"/>)</xsl:if>
+</xsl:if>
+</xsl:template>
+
+<xsl:template name="Error"><xsl:param name="text"/><xsl:param name="sub"/>
+<xsl:text>
Error: </xsl:text>
+<xsl:value-of select="$text"/>
+<xsl:if test="$sub!=''"> (<xsl:value-of select="$sub"/>)</xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
Binary file sysdeftools/xalan.jar has changed
Binary file sysdeftools/xercesImpl.jar has changed
Binary file sysdeftools/xml-apis.jar has changed